Skip to content

Commit c31a803

Browse files
committed
Installing purchased apps is now semi-functional
1 parent 18d12a3 commit c31a803

File tree

3 files changed

+207
-137
lines changed

3 files changed

+207
-137
lines changed

AirWatchBuddy/AppDelegate.m

Lines changed: 91 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#import <Security/Security.h>
1414
#import <MapKit/MapKit.h>
1515

16-
#define theSpan 0.30f;
1716
static NSString *const kServerURIUser = @"/api/mdm/devices/search";
1817
static NSString *const kServerURIDevices = @"/api/mdm/devices";
1918
static NSString *const kServerURIGPS = @"/api/mdm/devices/gps";
@@ -25,8 +24,7 @@
2524
static NSString *const kServerInternalApps = @"/api/mam/apps/public";
2625
static NSString *const kServerPurchasedApps = @"/api/mam/apps/purchasedappsearch";
2726
static NSString *const kServerAllApps = @"/api/mam/apps/search";
28-
static NSString *const kServerURIInstallApp = @"/api/mam/apps/purchased/";
29-
27+
static NSString *const kServerURIInstallPurchasedApp = @"/api/mam/apps/purchased/";
3028

3129
@interface AppDelegate ()
3230
@property (weak) IBOutlet NSWindow *window;
@@ -85,13 +83,13 @@ - (IBAction)closeSecWindow:(id)sender;
8583

8684
// App Install Window
8785
@property (weak) IBOutlet NSWindow *availableApps;
88-
@property (weak) IBOutlet NSTableView *installAppsTable;
86+
@property (weak) IBOutlet NSTableView *installAppsTableView;
8987
@property NSArray *installAppsTableArray;
90-
- (IBAction)installAppsTable:(id)sender;
88+
- (IBAction)installAppsTableView:(id)sender;
9189
- (IBAction)installApp:(id)sender;
9290
@property NSDictionary *installAppDict;
9391

94-
92+
// Main Window
9593
@property (weak) IBOutlet NSTextField *searchValue;
9694
@property (weak) IBOutlet NSPopUpButtonCell *searchParamater;
9795
@property (weak) IBOutlet NSPopUpButton *maxDeviceSearch;
@@ -123,9 +121,13 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
123121
NSArray *creds = [self getCredsFromKeychainWithUserName:storedUsername serverURL:storedServerURL];
124122
if (storedServerURL) {
125123
self.serverURL.stringValue = storedServerURL;
124+
} else {
125+
[self changeCredentials:self];
126126
}
127127
if (storedUsername) {
128128
self.userName.stringValue = storedUsername;
129+
} else {
130+
[self changeCredentials:self];
129131
}
130132
if (creds.count == 2) {
131133
self.password.stringValue = creds.firstObject;
@@ -139,7 +141,7 @@ - (void)setCredsToKeychainWithUserName:(NSString *)userName serverURL:(NSString
139141
void *passwordAndAPIKey = NULL;
140142
UInt32 passwordandAPIKeyLength = 0;
141143
NSString *creds = [[password stringByAppendingString:@"\n"] stringByAppendingString:awTenantCode];
142-
SecKeychainItemRef *keychainRef = NULL;
144+
SecKeychainItemRef keychainRef = NULL;
143145
NSString *currentUserName = [[NSUserDefaults standardUserDefaults] valueForKey:@"Username"];
144146
NSString *currentServerURL = [[NSUserDefaults standardUserDefaults] valueForKey:@"ServerURL"];
145147
// Before trying to create or update the keychain, we need to try and find it, which allows us to set the keychainRef pointer properly
@@ -200,12 +202,9 @@ - (void)setCredsToKeychainWithUserName:(NSString *)userName serverURL:(NSString
200202
[[NSUserDefaults standardUserDefaults] setValue:userName forKey:@"Username"];
201203
[[NSUserDefaults standardUserDefaults] setValue:serverURL forKey:@"ServerURL"];
202204
}
203-
// if ([serverURL isEqualToString:currentServerURL]) {
204-
//
205-
// OSStatus ret = SecKeychainItemModifyAttributesAndData(keychainRef, NULL, (UInt32)creds.length, (void *)creds.UTF8String);
206-
// }
207205
} else {
208-
OSStatus ret = SecKeychainAddGenericPassword(NULL, (UInt32)serverURL.length, serverURL.UTF8String, (UInt32)userName.length, userName.UTF8String, (UInt32)creds.length, (void *)creds.UTF8String, keychainRef);
206+
OSStatus ret = SecKeychainAddGenericPassword(NULL, (UInt32)serverURL.length, serverURL.UTF8String, (UInt32)userName.length, userName.UTF8String, (UInt32)creds.length, (void *)creds.UTF8String, &keychainRef);
207+
209208
//NSLog(@"The return code from trying to add the keychain entry: %d", ret);
210209
if (ret != errSecSuccess) {
211210
// Should show an NSAlert here about how it couldn't set a keychain
@@ -218,6 +217,7 @@ - (void)setCredsToKeychainWithUserName:(NSString *)userName serverURL:(NSString
218217
return;
219218
}];
220219
}
220+
CFRelease(keychainRef);
221221

222222
[[NSUserDefaults standardUserDefaults] setValue:userName forKey:@"Username"];
223223
[[NSUserDefaults standardUserDefaults] setValue:serverURL forKey:@"ServerURL"];
@@ -1053,14 +1053,13 @@ - (IBAction)getSecurityInfo:(id)sender {
10531053
//}
10541054

10551055

1056-
- (NSDictionary *)makePostRequest:(NSString *)URIPath serialNumber:(NSString *)serialNumber postData:(NSDictionary *)postData{
1056+
- (NSDictionary *)sendPostRequest:(NSString *)URIPath serialNumber:(NSString *)serialNumber {
10571057
// Create the URL request with the hostname and search URI's
10581058
NSURLComponents *airWatchURLComponents = [NSURLComponents componentsWithString:self.serverURL.stringValue];
1059-
//NSString *serialNumberPlusGPS = [[@"/" stringByAppendingString:serialNumber] stringByAppendingString:@"/gps"];
10601059
airWatchURLComponents.path = URIPath;
1061-
NSURLQueryItem *serialNumberParamater = [NSURLQueryItem queryItemWithName:@"searchby" value:@"serialnumber"];
1062-
NSURLQueryItem *serialNumberValue = [NSURLQueryItem queryItemWithName:@"id" value:serialNumber];
1063-
airWatchURLComponents.queryItems = @[ serialNumberParamater, serialNumberValue ];
1060+
NSDictionary *postData = [[NSDictionary alloc] initWithObjectsAndKeys:@"SerialNumber", serialNumber , nil];
1061+
NSError *error;
1062+
NSData *JSONPostData = [NSJSONSerialization dataWithJSONObject:postData options:0 error:&error];
10641063

10651064
// Create the base64 encoded authentication
10661065
NSString *authenticationString = [NSString stringWithFormat:@"%@:%@", self.userName.stringValue, self.password.stringValue];
@@ -1074,6 +1073,7 @@ - (NSDictionary *)makePostRequest:(NSString *)URIPath serialNumber:(NSString *)s
10741073
[URLRequest addValue:self.awTenantCode.stringValue forHTTPHeaderField:@"aw-tenant-code"];
10751074
[URLRequest addValue:@"application/json" forHTTPHeaderField:@"Accept"];
10761075
[URLRequest addValue:totalAuthHeader forHTTPHeaderField:@"Authorization"];
1076+
[URLRequest setHTTPBody:JSONPostData];
10771077
URLRequest.HTTPMethod = @"POST";
10781078

10791079
// Create the semaphore
@@ -1158,10 +1158,11 @@ - (IBAction)installPurchasedApplication:(id)sender {
11581158
//NSLog(@"%@", returnedJSON);
11591159
NSMutableArray *appsArray = [NSMutableArray array];
11601160
appsArray = returnedJSON[@"Application"];
1161+
NSLog(@"%@", appsArray);
11611162
NSArray *descriptor = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"ApplicationName" ascending:YES]];
11621163
NSArray *sortedApps = [appsArray sortedArrayUsingDescriptors:descriptor];
11631164
self.installAppsTableArray = sortedApps;
1164-
[self.installAppsTable reloadData];
1165+
[self.installAppsTableView reloadData];
11651166
dispatch_semaphore_signal(sema);
11661167
}] resume];
11671168

@@ -1228,8 +1229,77 @@ - (IBAction)closeNetworkWindow:(id)sender {
12281229
[self.window endSheet:self.networkWindow];
12291230
}
12301231
- (IBAction)installApp:(id)sender {
1231-
//NSInteger selectedRow = [self.deviceTableView selectedRow];
1232-
//[self makePostRequest:kServerURIInstallApp serialNumber:self.deviceTableArray[selectedRow][@"SerialNumber"] postData:self.installAppDict];
1232+
NSInteger deviceSelectedRow = [self.deviceTableView selectedRow];
1233+
NSString *serialNumber = self.deviceTableArray[deviceSelectedRow][@"SerialNumber"];
1234+
NSLog(@"Sending install command for serial: %@", serialNumber);
1235+
1236+
NSInteger appSelectedRow = [self.installAppsTableView selectedRow];
1237+
NSNumber *appToInstall = self.installAppsTableArray[appSelectedRow][@"Id"][@"Value"];
1238+
NSLog(@"Installing app: %@", appToInstall);
1239+
// Create the URL request with the hostname and search URI's
1240+
NSURLComponents *airWatchURLComponents = [NSURLComponents componentsWithString:self.serverURL.stringValue];
1241+
1242+
airWatchURLComponents.path = [[kServerURIInstallPurchasedApp stringByAppendingString:appToInstall.stringValue] stringByAppendingString:@"/install"];
1243+
NSDictionary *postData = [[NSDictionary alloc] initWithObjectsAndKeys:serialNumber, @"SerialNumber", nil];
1244+
NSError *error;
1245+
NSData *JSONPostData = [NSJSONSerialization dataWithJSONObject:postData options:0 error:&error];
1246+
if (JSONPostData) {
1247+
// process the data
1248+
} else {
1249+
NSLog(@"Unable to serialize the data %@: %@", postData, error);
1250+
}
1251+
1252+
// Create the base64 encoded authentication
1253+
NSString *authenticationString = [NSString stringWithFormat:@"%@:%@", self.userName.stringValue, self.password.stringValue];
1254+
NSData *authenticationData = [authenticationString dataUsingEncoding:NSASCIIStringEncoding];
1255+
NSString *b64AuthenticationString = [authenticationData base64EncodedStringWithOptions:0];
1256+
NSString *totalAuthHeader = [@"Basic " stringByAppendingString:b64AuthenticationString];
1257+
//NSLog(@"Base64 Encoded Creds: %@", b64AuthenticationString);
1258+
1259+
// Complete the URL request and add-in headers
1260+
NSMutableURLRequest *URLRequest = [NSMutableURLRequest requestWithURL:airWatchURLComponents.URL];
1261+
[URLRequest addValue:self.awTenantCode.stringValue forHTTPHeaderField:@"aw-tenant-code"];
1262+
[URLRequest addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
1263+
[URLRequest addValue:totalAuthHeader forHTTPHeaderField:@"Authorization"];
1264+
[URLRequest setHTTPBody:JSONPostData];
1265+
URLRequest.HTTPMethod = @"POST";
1266+
1267+
// Create the semaphore
1268+
1269+
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
1270+
// Run the query using the URL request and return the JSON
1271+
NSURLSession *session = [NSURLSession sharedSession];
1272+
[[session dataTaskWithRequest:URLRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
1273+
1274+
if (!data) return;
1275+
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
1276+
if ([httpResponse statusCode] != 200) {
1277+
NSDictionary *returnedJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
1278+
NSString *errorMessage;
1279+
if (!returnedJSON[@"Message"]) {
1280+
errorMessage = @"Something went wrong.";
1281+
} else {
1282+
errorMessage = returnedJSON[@"Message"];
1283+
}
1284+
dispatch_async(dispatch_get_main_queue(), ^{
1285+
NSAlert *alert = [[NSAlert alloc] init];
1286+
[alert addButtonWithTitle:@"OK"];
1287+
[alert setMessageText:@"Received a bad response from the server."];
1288+
[alert setInformativeText:errorMessage];
1289+
[alert setAlertStyle:NSAlertStyleWarning];
1290+
[alert beginSheetModalForWindow:self.window completionHandler:^(NSModalResponse returnCode) {
1291+
return;
1292+
}];
1293+
});
1294+
return;
1295+
}
1296+
dispatch_semaphore_signal(sema);
1297+
1298+
}] resume];
1299+
1300+
if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC))) {
1301+
NSLog(@"Timeout");
1302+
}
12331303
}
12341304

12351305
- (IBAction)quit:(id)sender {
@@ -1240,6 +1310,6 @@ - (void)applicationWillTerminate:(NSNotification *)aNotification {
12401310
// Insert code here to tear down your application
12411311
}
12421312

1243-
- (IBAction)installAppsTable:(id)sender {
1313+
- (IBAction)installAppsTableView:(id)sender {
12441314
}
12451315
@end

0 commit comments

Comments
 (0)