From b8fc0306f147300e0547f33c026c23e7cbc399e3 Mon Sep 17 00:00:00 2001 From: RickMohr Date: Fri, 4 Mar 2016 13:43:43 -0500 Subject: [PATCH] In tree save/edit, post only writable fields Connects #263 Testing: * Make an instance whose `public` role can upload photos but nothing else * Verify that a `public` user can upload an image * Verify that an admin user can still create and edit trees --- .../Controllers/OTMTreeDetailViewController.m | 30 +++++++++++++++++-- OpenTreeMap/src/OTM/OTMEnvironment.h | 1 + OpenTreeMap/src/OTM/OTMEnvironment.m | 9 +++--- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/OpenTreeMap/src/OTM/Controllers/OTMTreeDetailViewController.m b/OpenTreeMap/src/OTM/Controllers/OTMTreeDetailViewController.m index 55ea288..c0db1d6 100644 --- a/OpenTreeMap/src/OTM/Controllers/OTMTreeDetailViewController.m +++ b/OpenTreeMap/src/OTM/Controllers/OTMTreeDetailViewController.m @@ -647,6 +647,7 @@ - (void)toggleEditMode:(BOOL)saveChanges if (saveChanges) { OTMLoginManager* loginManager = [SharedAppDelegate loginManager]; OTMUser *user = loginManager.loggedInUser; + NSMutableDictionary *writableData = [self getWritableFieldData]; if (self.data[@"plot"][@"id"] == nil) { // No 'id' parameter indicates that this is a new plot/tree @@ -655,7 +656,8 @@ - (void)toggleEditMode:(BOOL)saveChanges [[AZWaitingOverlayController sharedController] showOverlayWithTitle:@"Saving"]; NSArray *pendingImageData = [self stripPendingImageData]; - [[[OTMEnvironment sharedEnvironment] api] addPlotWithOptionalTree:data user:user callback:^(id json, NSError *err){ + [[[OTMEnvironment sharedEnvironment] api] addPlotWithOptionalTree:writableData user:user + callback:^(id json, NSError *err){ [[AZWaitingOverlayController sharedController] hideOverlay]; @@ -678,7 +680,7 @@ - (void)toggleEditMode:(BOOL)saveChanges [[AZWaitingOverlayController sharedController] showOverlayWithTitle:@"Saving"]; NSArray *pendingImageData = [self stripPendingImageData]; - [[[OTMEnvironment sharedEnvironment] api] updatePlotAndTree:data user:user callback:^(id json, NSError *err){ + [[[OTMEnvironment sharedEnvironment] api] updatePlotAndTree:writableData user:user callback:^(id json, NSError *err){ [[AZWaitingOverlayController sharedController] hideOverlay]; @@ -715,6 +717,30 @@ - (void)toggleEditMode:(BOOL)saveChanges [self resetHeaderPosition]; } +- (NSMutableDictionary *)getWritableFieldData { + NSMutableDictionary *writableData = [[NSMutableDictionary alloc] init]; + NSDictionary *fieldData = [[OTMEnvironment sharedEnvironment] fieldData]; + + for (NSString *model in @[@"plot", @"tree"]) { + NSDictionary *modelData = self.data[model]; + + if (modelData != nil) { + NSMutableDictionary *writableModelData = [[NSMutableDictionary alloc] init]; + + for (NSString *key in modelData) { + NSString *fieldKey = [NSString stringWithFormat:@"%@.%@", model, key]; + NSDictionary *field = fieldData[fieldKey]; + + if (field != nil && ([key isEqualToString:@"id"] || [field[@"can_write"] boolValue])) { + writableModelData[key] = modelData[key]; + } + } + writableData[model] = writableModelData; + } + } + return writableData; +} + - (void)addNewUdf:(NSNotification *)notification { NSDictionary *notificationData = (NSDictionary *)[notification object]; diff --git a/OpenTreeMap/src/OTM/OTMEnvironment.h b/OpenTreeMap/src/OTM/OTMEnvironment.h index 8512506..f591b99 100644 --- a/OpenTreeMap/src/OTM/OTMEnvironment.h +++ b/OpenTreeMap/src/OTM/OTMEnvironment.h @@ -102,6 +102,7 @@ extern NSString * const OTMEnvironmentDateStringShort; @property (nonatomic, strong) UIColor *buttonTextColor; @property (nonatomic, assign) BOOL pendingActive; @property (nonatomic, strong) NSArray *sectionTitles; +@property (nonatomic, strong) NSDictionary *fieldData; @property (nonatomic, strong) NSArray *fields; @property (nonatomic, strong) NSDictionary *sortKeys; @property (nonatomic, strong) NSArray *ecoFields; diff --git a/OpenTreeMap/src/OTM/OTMEnvironment.m b/OpenTreeMap/src/OTM/OTMEnvironment.m index ba159e9..e0feb39 100644 --- a/OpenTreeMap/src/OTM/OTMEnvironment.m +++ b/OpenTreeMap/src/OTM/OTMEnvironment.m @@ -201,20 +201,21 @@ - (void)updateEnvironmentWithDictionary:(NSDictionary *)dict { self.instance = [dict objectForKey:@"url"]; self.instanceId = [dict objectForKey:@"id"]; self.geoRev = [dict objectForKey:@"geoRevHash"]; - self.fields = [self fieldsFromDict:[dict objectForKey:@"fields"] orderedAndGroupedByDictArray:[dict objectForKey:@"field_key_groups"]]; + self.fieldData = [dict objectForKey:@"fields"]; + self.fields = [self fieldsFromDict:self.fieldData orderedAndGroupedByDictArray:[dict objectForKey:@"field_key_groups"]]; self.sectionTitles = [self sectionTitlesFromDictArray:[dict objectForKey:@"field_key_groups"]]; self.config = [dict objectForKey:@"config"]; self.mapViewTitle = [dict objectForKey:@"name"]; - self.photoFieldWritable = [[[[[dict objectForKey:@"fields"] objectForKey:@"treephoto.image"] objectForKey:@"can_write"] stringValue] isEqualToString:@"0"] ? NO : YES; + self.photoFieldWritable = [[[[self.fieldData objectForKey:@"treephoto.image"] objectForKey:@"can_write"] stringValue] isEqualToString:@"0"] ? NO : YES; [self setSearchRegionRadiusInMeters:[[dict objectForKey:@"extent_radius"] doubleValue]]; NSDictionary *missingAndStandardFilters = [dict objectForKey:@"search"]; NSArray *regFilters = [self filtersFromDictArray:missingAndStandardFilters[@"standard"] - usingFields:[dict objectForKey:@"fields"]]; + usingFields:self.fieldData]; NSArray *missingFilters = [self missingFiltersFromDictArray:missingAndStandardFilters[@"missing"] - usingFields:[dict objectForKey:@"fields"]]; + usingFields:self.fieldData]; self.filters = [regFilters arrayByAddingObjectsFromArray:missingFilters];