Added checkbox to toggle between global and entry based defaults for password generator

This commit is contained in:
michael starke
2014-10-21 20:27:54 +02:00
parent d00016ce52
commit 8dd86ab350
4 changed files with 136 additions and 90 deletions

View File

@@ -12,6 +12,8 @@
#import "MPUniqueCharactersFormatter.h"
#import "MPSettingsHelper.h"
#import "KPKEntry.h"
/*
0 - 20 Terrible
@@ -30,18 +32,11 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
MPPasswordStrong = 60
};
typedef NS_ENUM(NSUInteger, MPDefaultDomain) {
MPEntryDomain,
MPGlobalDomain,
};
#define MIN_PASSWORD_LENGTH 1
#define MAX_PASSWORD_LENGTH 256
@interface MPPasswordCreatorViewController () {
MPPasswordCharacterFlags _characterFlags;
MPDefaultDomain _defaultDomain;
}
@interface MPPasswordCreatorViewController ()
@property (nonatomic, copy) NSString *password;
@property (copy) NSString *generatedPassword;
@@ -58,12 +53,16 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) {
@property (weak) IBOutlet NSButton *setDefaultButton;
@property (weak) IBOutlet NSTextField *entropyTextField;
@property (weak) IBOutlet NSLevelIndicator *entropyIndicator;
@property (weak) IBOutlet NSButton *useEntryDefaultsButton;
@property (nonatomic, copy) NSString *customString;
@property (nonatomic, assign) BOOL useCustomString;
@property (nonatomic, assign) NSUInteger passwordLength;
@property (nonatomic, assign) CGFloat entropy;
@property (nonatomic, assign) BOOL useEntryDefaults;
@property (nonatomic, assign) MPPasswordCharacterFlags characterFlags;
@end
@implementation MPPasswordCreatorViewController
@@ -76,13 +75,10 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_password = @"";
_passwordLength = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyDefaultPasswordLength];
_characterFlags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyPasswordCharacterFlags];
_useCustomString = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyPasswordUseCustomString];
_customString = [[NSUserDefaults standardUserDefaults] stringForKey:kMPSettingsKeyPasswordCustomString];
_entropy = 0.0;
_defaultDomain = MPGlobalDomain;
_useEntryDefaults = NO;
_allowsEntryDefaults = NO;
[self _setupDefaults];
}
return self;
}
@@ -115,13 +111,19 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) {
NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController];
[self.shouldCopyPasswordToPasteboardButton bind:NSValueBinding toObject:defaultsController withKeyPath:copyToPasteBoardKeyPath options:nil];
if(self.allowsEntryDefaults) {
[self.useEntryDefaultsButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(useEntryDefaults)) options:nil];
}
else {
[self.useEntryDefaultsButton setEnabled:self.allowsEntryDefaults];
}
[self.numbersButton setTag:MPPasswordCharactersNumbers];
[self.upperCaseButton setTag:MPPasswordCharactersUpperCase];
[self.lowerCaseButton setTag:MPPasswordCharactersLowerCase];
[self.symbolsButton setTag:MPPasswordCharactersSymbols];
[self updateResponderChain];
[self _updateSetDefaultButton];
[self reset];
}
@@ -130,43 +132,31 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) {
[self _generatePassword:self];
}
#pragma mark -
#pragma mark Events
- (void)flagsChanged:(NSEvent *)theEvent {
if(!self.allowsEntryDefaults) {
return;
}
BOOL altIsDown = (0 != ([NSEvent modifierFlags] & NSAlternateKeyMask));
_defaultDomain = altIsDown ? MPEntryDomain : MPGlobalDomain;
[self _updateSetDefaultButton];
}
#pragma mark -
#pragma mark Actions
- (IBAction)_generatePassword:(id)sender {
if(_useCustomString) {
if([[_customCharactersTextField stringValue] length] > 0) {
self.password = [[_customCharactersTextField stringValue] passwordWithLength:_passwordLength];
if(self.useCustomString) {
if([[self.customCharactersTextField stringValue] length] > 0) {
self.password = [[self.customCharactersTextField stringValue] passwordWithLength:self.passwordLength];
}
}
else {
self.password = [NSString passwordWithCharactersets:_characterFlags length:_passwordLength];
self.password = [NSString passwordWithCharactersets:self.characterFlags length:self.passwordLength];
}
}
- (IBAction)_toggleCharacters:(id)sender {
[_setDefaultButton setEnabled:YES];
_characterFlags ^= [sender tag];
[self.setDefaultButton setEnabled:YES];
self.characterFlags ^= [sender tag];
self.useCustomString = NO;
[self reset];
}
- (IBAction)_usePassword:(id)sender {
self.generatedPassword = _password;
self.generatedPassword = self.password;
if([self.shouldCopyPasswordToPasteboardButton state] == NSOnState) {
[[MPPasteBoardController defaultController] copyObjects:@[_password]];
[[MPPasteBoardController defaultController] copyObjects:@[self.password]];
}
[[self _findCloseTarget] performClose:nil];
}
@@ -176,36 +166,67 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) {
}
- (IBAction)_setDefault:(id)sender {
[[NSUserDefaults standardUserDefaults] setInteger:_passwordLength forKey:kMPSettingsKeyDefaultPasswordLength];
[[NSUserDefaults standardUserDefaults] setInteger:_characterFlags forKey:kMPSettingsKeyPasswordCharacterFlags];
[[NSUserDefaults standardUserDefaults] setBool:_useCustomString forKey:kMPSettingsKeyPasswordUseCustomString];
[[NSUserDefaults standardUserDefaults] setObject:[_customCharactersTextField stringValue] forKey:kMPSettingsKeyPasswordCustomString];
[_setDefaultButton setEnabled:NO];
if(self.useEntryDefaults) {
NSMutableDictionary *entryDefaults = [[self _currentEntryDefaults] mutableCopy];
if(!entryDefaults) {
entryDefaults = [[NSMutableDictionary alloc] initWithCapacity:4]; // we will only add one enty to new settings
}
entryDefaults[kMPSettingsKeyDefaultPasswordLength] = @(self.passwordLength);
entryDefaults[kMPSettingsKeyPasswordCharacterFlags] = @(self.characterFlags);
entryDefaults[kMPSettingsKeyPasswordUseCustomString] = @(self.useCustomString);
entryDefaults[kMPSettingsKeyPasswordCustomString] = [self.customCharactersTextField stringValue];
NSMutableDictionary *availableDefaults = [[self _availableEntryDefaults] mutableCopy];
if(!availableDefaults) {
availableDefaults = [[NSMutableDictionary alloc] initWithCapacity:1];
}
availableDefaults[self.entry.uuid] = entryDefaults;
}
else {
[[NSUserDefaults standardUserDefaults] setInteger:self.passwordLength forKey:kMPSettingsKeyDefaultPasswordLength];
[[NSUserDefaults standardUserDefaults] setInteger:self.characterFlags forKey:kMPSettingsKeyPasswordCharacterFlags];
[[NSUserDefaults standardUserDefaults] setBool:self.useCustomString forKey:kMPSettingsKeyPasswordUseCustomString];
[[NSUserDefaults standardUserDefaults] setObject:[self.customCharactersTextField stringValue] forKey:kMPSettingsKeyPasswordCustomString];
}
[self.setDefaultButton setEnabled:NO];
}
#pragma mark -
#pragma mark Custom Setter
- (void)setUseEntryDefaults:(BOOL)useEntryDefaults {
if(self.useEntryDefaults != useEntryDefaults) {
_useEntryDefaults = useEntryDefaults;
[self _setupDefaults];
[self reset];
}
}
- (void)setEntry:(KPKEntry *)entry {
if(_entry != entry) {
_entry = entry;
[self _setupDefaults];
[self reset];
}
}
- (void)setPassword:(NSString *)password {
if(![_password isEqualToString:password]) {
_password = [password copy];
NSString *customString = _useCustomString ? [_customCharactersTextField stringValue] : nil;
self.entropy = [password entropyWhithPossibleCharacterSet:_characterFlags orCustomCharacters:customString];
NSString *customString = self.useCustomString ? [self.customCharactersTextField stringValue] : nil;
self.entropy = [password entropyWhithPossibleCharacterSet:self.characterFlags orCustomCharacters:customString];
}
}
- (void)setUseCustomString:(BOOL)useCustomString {
if(_useCustomString != useCustomString) {
[_setDefaultButton setEnabled:YES];
if(self.useCustomString != useCustomString) {
[self.setDefaultButton setEnabled:YES];
_useCustomString = useCustomString;
[self _resetCharacters];
}
}
- (void)setPasswordLength:(NSUInteger)passwordLength {
if(_passwordLength != passwordLength) {
[_setDefaultButton setEnabled:YES];
if(self.passwordLength != passwordLength) {
[self.setDefaultButton setEnabled:YES];
_passwordLength = passwordLength;
[self _generatePassword:nil];
}
@@ -216,52 +237,64 @@ typedef NS_ENUM(NSUInteger, MPDefaultDomain) {
- (void)controlTextDidChange:(NSNotification *)obj {
if([obj object] == self.customCharactersTextField) {
[_setDefaultButton setEnabled:YES];
[self.setDefaultButton setEnabled:YES];
[self _generatePassword:nil];
}
}
#pragma mark -
#pragma mark Helper
- (NSDictionary *)_availableEntryDefaults {
return [[NSUserDefaults standardUserDefaults] dictionaryForKey:kMPSettingsKeyPasswordDefaultsForEntry];
}
- (void)_updateSetDefaultButton {
switch (_defaultDomain) {
case MPEntryDomain:
[self.setDefaultButton setTitle:NSLocalizedString(@"SET_DEFAULT_ENTRY_PASSWORD_RULE", "")];
break;
case MPGlobalDomain:
default:
[self.setDefaultButton setTitle:NSLocalizedString(@"SET_DEFAULT_GENERAL_PASSWORD_RULE", "")];
break;
- (NSDictionary *)_currentEntryDefaults {
if(self.entry) {
return [self _availableEntryDefaults][self.entry.uuid];
}
return nil;
}
- (void)_setupDefaults {
NSDictionary *entryDefaults = [self _currentEntryDefaults];
if(entryDefaults) {
self.passwordLength = [entryDefaults[kMPSettingsKeyDefaultPasswordLength] integerValue];
self.characterFlags = [entryDefaults[kMPSettingsKeyPasswordCharacterFlags] integerValue];
self.useCustomString = [entryDefaults[kMPSettingsKeyPasswordUseCustomString] boolValue];
self.customString = [entryDefaults[kMPSettingsKeyPasswordCustomString] stringValue];
}
else {
self.passwordLength = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyDefaultPasswordLength];
self.characterFlags = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyPasswordCharacterFlags];
self.useCustomString = [[NSUserDefaults standardUserDefaults] boolForKey:kMPSettingsKeyPasswordUseCustomString];
self.customString = [[NSUserDefaults standardUserDefaults] stringForKey:kMPSettingsKeyPasswordCustomString];
}
}
- (void)_resetCharacters {
if(_useCustomString) {
[_customButton setState:NSOnState];
if(self.useCustomString) {
[self.customButton setState:NSOnState];
}
[_customCharactersTextField setEnabled:_useCustomString];
[_upperCaseButton setEnabled:!_useCustomString];
[_lowerCaseButton setEnabled:!_useCustomString];
[_numbersButton setEnabled:!_useCustomString];
[_symbolsButton setEnabled:!_useCustomString];
[self.customCharactersTextField setEnabled:_useCustomString];
[self.upperCaseButton setEnabled:!_useCustomString];
[self.lowerCaseButton setEnabled:!_useCustomString];
[self.numbersButton setEnabled:!_useCustomString];
[self.symbolsButton setEnabled:!_useCustomString];
/* Set to defualts, if we got nothing */
if(_characterFlags == 0) {
_characterFlags = MPPasswordCharactersAll;
/* Set to defaults, if we got nothing */
if(self.characterFlags == 0) {
self.characterFlags = MPPasswordCharactersAll;
}
const BOOL userLowercase = ( 0 != (MPPasswordCharactersLowerCase & _characterFlags));
const BOOL useUppercase = ( 0 != (MPPasswordCharactersUpperCase & _characterFlags) );
const BOOL useNumbers = ( 0 != (MPPasswordCharactersNumbers & _characterFlags) );
const BOOL useSymbols = ( 0 != (MPPasswordCharactersSymbols & _characterFlags) );
const BOOL userLowercase = ( 0 != (MPPasswordCharactersLowerCase & self.characterFlags));
const BOOL useUppercase = ( 0 != (MPPasswordCharactersUpperCase & self.characterFlags) );
const BOOL useNumbers = ( 0 != (MPPasswordCharactersNumbers & self.characterFlags) );
const BOOL useSymbols = ( 0 != (MPPasswordCharactersSymbols & self.characterFlags) );
[_upperCaseButton setState:useUppercase ? NSOnState : NSOffState];
[_lowerCaseButton setState:userLowercase ? NSOnState : NSOffState];
[_numbersButton setState:useNumbers ? NSOnState : NSOffState];
[_symbolsButton setState:useSymbols ? NSOnState : NSOffState];
[self.upperCaseButton setState:useUppercase ? NSOnState : NSOffState];
[self.lowerCaseButton setState:userLowercase ? NSOnState : NSOffState];
[self.numbersButton setState:useNumbers ? NSOnState : NSOffState];
[self.symbolsButton setState:useSymbols ? NSOnState : NSOffState];
}
- (id)_findCloseTarget {