user-preferences: rewrite + support for creds file

This is related to #1955
Remove support for specifying the user:pass on the CLI
Add support for credential file: -p filename

Rewrite the core of the run function to use a switch case instead
of ... what was there.
Sprinkle so error messages along the way.
This commit is contained in:
Jean Raby 2013-01-07 15:07:17 -05:00
parent a75c797553
commit ea904f2e05

View file

@ -21,9 +21,11 @@
*/ */
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSCharacterSet.h>
#import <Foundation/NSData.h> #import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
#import <Foundation/NSUserDefaults.h>
#import <SOGo/NSString+Utilities.h> #import <SOGo/NSString+Utilities.h>
#import <SOGo/SOGoUser.h> #import <SOGo/SOGoUser.h>
@ -62,9 +64,12 @@ typedef enum
- (void) usage - (void) usage
{ {
fprintf (stderr, "user-preferences get|set|unset defaults|settings user [authname:authpassword] key [value|-f filename]\n\n" fprintf (stderr, "user-preferences get|set|unset defaults|settings user [-p credentialFile] key [value|-f filename]\n\n"
" user the user of whom to set the defaults/settings key/value\n" " user the user of whom to set the defaults/settings key/value\n"
" value the JSON-formatted value of the key\n\n" " value the JSON-formatted value of the key\n\n"
" -p credentialFile Specify the file containing the sieve admin credentials\n"
" The file should contain a single line:\n"
" username:password\n"
" Examples:\n" " Examples:\n"
" sogo-tool user-preferences get defaults janedoe SOGoLanguage\n" " sogo-tool user-preferences get defaults janedoe SOGoLanguage\n"
" sogo-tool user-preferences unset settings janedoe Mail\n" " sogo-tool user-preferences unset settings janedoe Mail\n"
@ -98,22 +103,44 @@ typedef enum
- (BOOL) _updateSieveScripsForkey: (NSString *) theKey - (BOOL) _updateSieveScripsForkey: (NSString *) theKey
manager: (SOGoSieveManager *) theManager manager: (SOGoSieveManager *) theManager
login: (NSString *) theLogin login: (NSString *) theLogin
authname: (NSString *) theAuthName
password: (NSString *) thePassword
{ {
if ([theKey caseInsensitiveCompare: @"Forward"] == NSOrderedSame || if ([theKey caseInsensitiveCompare: @"Forward"] == NSOrderedSame ||
[theKey caseInsensitiveCompare: @"SOGoSieveFilters"] == NSOrderedSame || [theKey caseInsensitiveCompare: @"SOGoSieveFilters"] == NSOrderedSame ||
[theKey caseInsensitiveCompare: @"Vacation"] == NSOrderedSame) [theKey caseInsensitiveCompare: @"Vacation"] == NSOrderedSame)
{ {
if ([theAuthName length] == 0 || [thePassword length] == 0) /* credentials file handling */
NSRange r;
NSString *credsFile, *creds, *authname, *authpwd;
authname = nil;
authpwd = nil;
credsFile = [[NSUserDefaults standardUserDefaults] stringForKey: @"p"];
if (credsFile)
{ {
NSLog(@"To update Sieve scripts, you must provide the \"authname:password\" parameter"); /* TODO: add back support for user:pwd here? */
creds = [NSString stringWithContentsOfFile: credsFile
encoding: NSUTF8StringEncoding
error: NULL];
if (creds == nil)
{
NSLog(@"Error reading credential file '%@'", credsFile);
return NO;
}
creds = [creds stringByTrimmingCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
r = [creds rangeOfString: @":"];
authname = [creds substringToIndex: r.location];
authpwd = [creds substringFromIndex: r.location+1];
}
if (authname == nil || authpwd == nil)
{
NSLog(@"To update Sieve scripts, you must provide the \"-p credentialFile\" parameter");
return NO; return NO;
} }
return [theManager updateFiltersForLogin: theLogin return [theManager updateFiltersForLogin: theLogin
authname: theAuthName authname: authname
password: thePassword password: authpwd
account: nil]; account: nil];
} }
@ -121,17 +148,18 @@ typedef enum
} }
- (BOOL) run - (BOOL) run
{ {
NSString *userId, *type, *key; NSString *userId, *type, *key, *value;
NSString *jsonValueFile;
SOGoUserPreferencesCommand cmd; SOGoUserPreferencesCommand cmd;
id o; id o;
NSRange r;
BOOL rc; BOOL rc;
int max; int max;
max = [arguments count]; max = [sanitizedArguments count];
rc = NO; rc = NO;
if (max > 3) if (max > 3)
@ -140,13 +168,11 @@ typedef enum
SOGoSieveManager *manager; SOGoSieveManager *manager;
SOGoUser *user; SOGoUser *user;
cmd = [self _cmdFromString: [arguments objectAtIndex: 0]]; cmd = [self _cmdFromString: [sanitizedArguments objectAtIndex: 0]];
if (cmd != UserPreferencesUnknown) type = [sanitizedArguments objectAtIndex: 1];
{ userId = [sanitizedArguments objectAtIndex: 2];
type = [arguments objectAtIndex: 1]; key = [sanitizedArguments objectAtIndex: 3];
userId = [arguments objectAtIndex: 2];
key = [arguments objectAtIndex: 3];
user = [SOGoUser userWithLogin: userId]; user = [SOGoUser userWithLogin: userId];
manager = [SOGoSieveManager sieveManagerForUser: user]; manager = [SOGoSieveManager sieveManagerForUser: user];
@ -156,74 +182,55 @@ typedef enum
else else
source = [user userSettings]; source = [user userSettings];
if (cmd == UserPreferencesGet) switch (cmd)
{ {
case UserPreferencesGet:
o = [source objectForKey: key]; o = [source objectForKey: key];
if (o) if (o)
{
printf("%s: %s\n", [key UTF8String], [[o jsonRepresentation] UTF8String]); printf("%s: %s\n", [key UTF8String], [[o jsonRepresentation] UTF8String]);
else
NSLog(@"Value for key \"%@\" not found in %@", key, type);
rc = YES; rc = YES;
} }
else else
{ {
NSString *authname, *authpwd, *value; NSLog(@"Value for key \"%@\" not found in %@", key, type);
NSData *data; return rc;
int i; }
break;
authname = @"";
authpwd = @"";
value = @"";
case UserPreferencesSet:
if (max > 4) if (max > 4)
{ {
r = [[arguments objectAtIndex: 3] rangeOfString: @":"]; /* value specified on command line */
if (r.location == NSNotFound) value = [sanitizedArguments objectAtIndex: 4];
{
i = 3;
} }
else else
{ {
authname = [[arguments objectAtIndex: 3] substringToIndex: r.location]; /* value is to be found in file specified with -f filename */
authpwd = [[arguments objectAtIndex: 3] substringFromIndex: r.location+1]; jsonValueFile = [[NSUserDefaults standardUserDefaults]
i = 4; stringForKey: @"f"];
if (jsonValueFile == nil)
{
NSLog(@"No value specified, aborting");
[self usage];
return rc;
} }
else
{
key = [arguments objectAtIndex: i++]; NSData *data = [NSData dataWithContentsOfFile: jsonValueFile];
if (data == nil)
if (max > i)
{ {
value = [arguments objectAtIndex: i++]; NSLog(@"Error reading file '%@'", jsonValueFile);
if ([value caseInsensitiveCompare: @"-f"] == NSOrderedSame) [self usage];
{ return rc;
if (max > i) }
{
data = [NSData dataWithContentsOfFile: [arguments objectAtIndex: i]];
value = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; value = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
[value autorelease]; [value autorelease];
} }
} }
}
}
else
{
if (cmd == UserPreferencesUnset)
{
key = [arguments objectAtIndex: 3];
}
else
{
key = [arguments objectAtIndex: 3];
value = [arguments objectAtIndex: 4];
}
}
if (cmd == UserPreferencesUnset)
[source removeObjectForKey: key];
else
{
o = [value objectFromJSONString]; o = [value objectFromJSONString];
// //
@ -251,16 +258,35 @@ typedef enum
[source setObject: o forKey: key]; [source setObject: o forKey: key];
} }
else else
{
NSLog(@"Invalid JSON input - no changes performed in the database. The supplied value was: %@", value); NSLog(@"Invalid JSON input - no changes performed in the database. The supplied value was: %@", value);
[self usage];
return rc;
} }
[source synchronize];
rc = [self _updateSieveScripsForkey: key rc = [self _updateSieveScripsForkey: key
manager: manager manager: manager
login: userId login: userId];
authname: authname if (rc)
password: authpwd]; [source synchronize];
} else
NSLog(@"Error updating sieve script, not updating database");
break;
case UserPreferencesUnset:
[source removeObjectForKey: key];
rc = [self _updateSieveScripsForkey: key
manager: manager
login: userId];
if (rc)
[source synchronize];
else
NSLog(@"Error updating sieve script, not updating database");
break;
case UserPreferencesUnknown:
break;
} }
} }