Add “Contact” part in the settings, allowing the addition, deletion and edition of LDAP configurations

This commit is contained in:
QuentinArguillere 2022-05-04 16:36:51 +02:00
parent 6ff68174b1
commit e10cb36cad
7 changed files with 655 additions and 6 deletions

View file

@ -22,10 +22,10 @@
#import "PhoneMainView.h"
#import "SVProgressHUD.h"
#import "ShareViewController.h"
#import "linphoneapp-Swift.h"
#import <UIKit/UIKit.h>
@implementation ImagePickerView
@synthesize imagePickerDelegate;

View file

@ -30,6 +30,8 @@
- (void)transformLinphoneCoreToKeys;
- (void)transformAccountToKeys:(NSString *)username;
- (void)transformLdapToKeys:(NSString *)ldap_server;
- (void)removeAccount;
- (void)removeLdap;
@end

View file

@ -257,6 +257,87 @@
}
}
- (void)transformLdapToKeys:(NSString *)ldap_server {
const MSList *ldaps = linphone_core_get_ldap_list(LC);
while (ldap_server && ldaps &&
strcmp(ldap_server.UTF8String,
linphone_ldap_params_get_server(linphone_ldap_get_params(ldaps->data))) != 0) {
ldaps = ldaps->next;
}
LinphoneLdap *ldap = NULL;
// default values
{
[self setBool:YES forKey:@"ldap_enabled"];
[self setObject:@"" forKey:@"ldap_server"];
[self setObject:@"" forKey:@"ldap_bind_dn"];
[self setObject:@"" forKey:@"ldap_password"];
[self setObject:@"simple" forKey:@"ldap_auth_method"];
[self setBool:YES forKey:@"ldap_tls_enabled"];
[self setObject:@"default" forKey:@"ldap_certificates_verification_mode"];
[self setObject:@"" forKey:@"ldap_filter"];
[self setInteger:50 forKey:@"ldap_max_results"];
[self setInteger:5 forKey:@"ldap_timeout"];
[self setInteger:500 forKey:@"ldap_delay"];
[self setInteger:3 forKey:@"ldap_min_chars"];
[self setObject:@"" forKey:@"ldap_name_attribute"];
[self setObject:@"" forKey:@"ldap_sip_attribute"];
[self setObject:@"" forKey:@"ldap_sip_domain"];
[self setBool:NO forKey:@"ldap_logs_enabled"];
}
if (ldaps) {
ldap = ldaps->data;
LinphoneLdapParams const *ldapParams = linphone_ldap_get_params(ldap);
int idx = (int)bctbx_list_index(linphone_core_get_ldap_list(LC), ldap);
[self setInteger:idx forKey:@"current_ldap_index"];
[self setBool:linphone_ldap_params_get_enabled(ldapParams) forKey:@"ldap_enabled"];
[self setCString:linphone_ldap_params_get_server(ldapParams) forKey:@"ldap_server"];
[self setCString:linphone_ldap_params_get_bind_dn(ldapParams) forKey:@"ldap_bind_dn"];
[self setCString:linphone_ldap_params_get_password(ldapParams) forKey:@"ldap_password"];
[self setBool:linphone_ldap_params_tls_enabled(ldapParams) forKey:@"ldap_tls_enabled"];
switch (linphone_ldap_params_get_auth_method(ldapParams)) {
case LinphoneLdapAuthMethodSimple:
[self setObject:@"simple" forKey:@"ldap_auth_method"];
break;
case LinphoneLdapAuthMethodAnonymous:
[self setObject:@"anonymous" forKey:@"ldap_auth_method"];
break;
}
switch (linphone_ldap_params_get_server_certificates_verification_mode(ldapParams)) {
case LinphoneLdapCertVerificationDefault:
[self setObject:@"default" forKey:@"ldap_certificates_verification_mode"];
break;
case LinphoneLdapCertVerificationEnabled:
[self setObject:@"enabled" forKey:@"ldap_certificates_verification_mode"];
break;
case LinphoneLdapCertVerificationDisabled:
[self setObject:@"disabled" forKey:@"ldap_certificates_verification_mode"];
break;
}
[self setCString:linphone_ldap_params_get_base_object(ldapParams) forKey:@"ldap_base_object"];
[self setCString:linphone_ldap_params_get_filter(ldapParams) forKey:@"ldap_filter"];
[self setInteger:linphone_ldap_params_get_max_results(ldapParams) forKey:@"ldap_max_results"];
[self setInteger:linphone_ldap_params_get_timeout(ldapParams) forKey:@"ldap_timeout"];
[self setInteger:linphone_ldap_params_get_delay(ldapParams) forKey:@"ldap_delay"];
[self setInteger:linphone_ldap_params_get_min_chars(ldapParams) forKey:@"ldap_min_chars"];
[self setCString:linphone_ldap_params_get_name_attribute(ldapParams) forKey:@"ldap_name_attribute"];
[self setCString:linphone_ldap_params_get_sip_attribute(ldapParams) forKey:@"ldap_sip_attribute"];
[self setCString:linphone_ldap_params_get_sip_domain(ldapParams) forKey:@"ldap_sip_domain"];
bool ldapLogsEnabled = linphone_ldap_params_get_debug_level(ldapParams) == LinphoneLdapDebugLevelVerbose;
[self setBool:ldapLogsEnabled forKey:@"ldap_logs_enabled"];
}
}
- (void)transformLinphoneCoreToKeys {
LinphoneManager *lm = LinphoneManager.instance;
@ -424,6 +505,11 @@
[self setInteger:443 forKey:@"tunnel_port_preference"];
}
}
// contacts section
if (linphone_core_ldap_available(LC)) {
[self transformLdapToKeys:nil];
}
// advanced section
{
@ -687,6 +773,71 @@
}
}
- (void)synchronizeLdap {
LOGI(@"LDAP config changed, synchronizing.");
LinphoneLdap*ldap = bctbx_list_nth_data(linphone_core_get_ldap_list(LC), [self integerForKey:@"current_ldap_index"]);
if (!ldap) {
return;
}
if ([self stringForKey:@"ldap_base_object"].length == 0) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Error", nil)
message:@"LDAPResearch base must not be empty"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
[errView addAction:defaultAction];
[PhoneMainView.instance presentViewController:errView animated:YES completion:nil];
return;
}
LinphoneLdapParams *newLdapParams = linphone_ldap_params_clone(linphone_ldap_get_params(ldap));
// Connexion parameters
linphone_ldap_params_set_enabled(newLdapParams, [self boolForKey:@"ldap_enabled"]);
linphone_ldap_params_set_server(newLdapParams, [self stringForKey:@"ldap_server"].UTF8String);
linphone_ldap_params_set_bind_dn(newLdapParams, [self stringForKey:@"ldap_bind_dn"].UTF8String);
linphone_ldap_params_set_password(newLdapParams, [self stringForKey:@"ldap_password"].UTF8String);
LinphoneLdapAuthMethod authMethod = [[self stringForKey:@"ldap_verification_method"] isEqualToString:@"simple"] ? LinphoneLdapAuthMethodSimple : LinphoneLdapAuthMethodAnonymous;
linphone_ldap_params_set_auth_method(newLdapParams, authMethod);
linphone_ldap_params_enable_tls(newLdapParams, [self boolForKey:@"ldap_tls_enabled"]);
LinphoneLdapCertVerificationMode certVerifMode = LinphoneLdapCertVerificationDefault;
NSString *certVerifModeStr = [self stringForKey:@"ldap_certificates_verification_mode"];
if ([certVerifModeStr isEqualToString:@"enabled"])
certVerifMode = LinphoneLdapCertVerificationEnabled;
else if ([certVerifModeStr isEqualToString:@"disabled"])
certVerifMode = LinphoneLdapCertVerificationEnabled;
linphone_ldap_params_set_server_certificates_verification_mode(newLdapParams, certVerifMode);
// Research parameters
linphone_ldap_params_set_base_object(newLdapParams, [self stringForKey:@"ldap_base_object"].UTF8String);
linphone_ldap_params_set_filter(newLdapParams, [self stringForKey:@"ldap_filter"].UTF8String);
linphone_ldap_params_set_max_results(newLdapParams, [self integerForKey:@"ldap_max_results"]);
linphone_ldap_params_set_timeout(newLdapParams, [self integerForKey:@"ldap_timeout"]);
linphone_ldap_params_set_delay(newLdapParams, [self integerForKey:@"ldap_delay"]);
linphone_ldap_params_set_min_chars(newLdapParams, [self integerForKey:@"ldap_min_chars"]);
// Analysis parameters
linphone_ldap_params_set_name_attribute(newLdapParams, [self stringForKey:@"ldap_name_attributes"].UTF8String);
linphone_ldap_params_set_sip_attribute(newLdapParams, [self stringForKey:@"ldap_sip_attributes"].UTF8String);
linphone_ldap_params_set_sip_domain(newLdapParams, [self stringForKey:@"ldap_sip_domain"].UTF8String);
// Miscellaneous parameters
LinphoneLdapDebugLevel debugLevel = [self boolForKey:@"ldap_logs_enabled"] ? LinphoneLdapDebugLevelVerbose : LinphoneLdapDebugLevelOff;
linphone_ldap_params_set_debug_level(newLdapParams, debugLevel);
linphone_ldap_set_params(ldap, newLdapParams);
}
- (BOOL)synchronize {
@try {
LinphoneManager *lm = LinphoneManager.instance;
@ -705,7 +856,7 @@
if (account_changed)
[self synchronizeAccounts];
bool enableVideo = [self boolForKey:@"enable_video_preference"];
linphone_core_enable_video_capture(LC, enableVideo);
linphone_core_enable_video_display(LC, enableVideo);
@ -911,6 +1062,19 @@
linphone_tunnel_set_mode(tunnel, mode);
}
// contacts section
BOOL ldap_changed = NO;
for (NSString *key in self->changedDict) {
if ([key hasPrefix:@"ldap_"] && [self valueChangedForKey:key]) {
ldap_changed = YES;
break;
}
}
if (ldap_changed)
[self synchronizeLdap];
// advanced section
BOOL animations = [self boolForKey:@"animations_preference"];
[lm lpConfigSetInt:animations forKey:@"animations_preference"];
@ -1012,4 +1176,11 @@
}
[self transformLinphoneCoreToKeys];
}
- (void)removeLdap {
LinphoneLdap *ldap = bctbx_list_nth_data(linphone_core_get_ldap_list(LC),
[self integerForKey:@"current_ldap_index"]);
linphone_core_remove_ldap(LC, ldap);
[self transformLinphoneCoreToKeys];
}
@end

View file

@ -592,7 +592,33 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
[specifier.specifierDict setValue:name forKey:kIASKTitle];
}
}
if ([specifier.key hasPrefix:@"ldap_"]) {
if (linphone_core_ldap_available(LC)) {
const bctbx_list_t *ldaps = linphone_core_get_ldap_list(LC);
int index = [specifier.key substringFromIndex:@"ldap_".length].intValue - 1;
if (index < bctbx_list_size(ldaps)) {
const LinphoneLdapParams *ldapParams = linphone_ldap_get_params(bctbx_list_nth_data(ldaps, index));
NSString *name = [NSString
stringWithUTF8String:linphone_ldap_params_get_server(ldapParams)];
[specifier.specifierDict setValue:name forKey:kIASKTitle];
}
}
}
if ([[specifier key] isEqualToString:@"ldap_auth_method"]) {
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:[specifier specifierDict]];
NSMutableArray *titles = [NSMutableArray arrayWithArray:[dict objectForKey:@"Titles"]];
[titles removeObject:@"TLS"];
[dict setObject:titles forKey:@"Titles"];
NSMutableArray *values = [NSMutableArray arrayWithArray:[dict objectForKey:@"Values"]];
[values removeObject:@"tls"];
[dict setObject:values forKey:@"Values"];
return [[IASKSpecifier alloc] initWithSpecifier:dict];
}
return specifier;
}
@ -605,10 +631,17 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
[hiddenKeys addObject:[NSString stringWithFormat:@"menu_account_%lu", i]];
}
const MSList *ldaps = linphone_core_get_ldap_list(LC);
for (size_t i = bctbx_list_size(ldaps) + 1; i <= 5; i++) {
[hiddenKeys addObject:[NSString stringWithFormat:@"ldap_%lu", i]];
}
if (!linphone_core_sip_transport_supported(LC, LinphoneTransportTls)) {
[hiddenKeys addObject:@"media_encryption_preference"];
}
if (!linphone_core_ldap_available(LC)) {
[hiddenKeys addObject:@"contacts_menu"];
}
#ifndef DEBUG
[hiddenKeys addObject:@"debug_actions_group"];
[hiddenKeys addObject:@"release_button"];
@ -743,6 +776,17 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
[[_settingsController tableView] reloadData];
}
-(void)recomputeLdapLabelsAndSync {
// it's a bit violent... but IASK is not designed to dynamically change subviews' name
_settingsController.hiddenKeys = [self findHiddenKeys];
[_settingsController.settingsReader indexPathForKey:@"ldap_1"]; // force refresh ldap server name display
[_settingsController.settingsReader indexPathForKey:@"ldap_2"]; // force refresh ldap server name display
[_settingsController.settingsReader indexPathForKey:@"ldap_3"]; // force refresh ldap server name display
[_settingsController.settingsReader indexPathForKey:@"ldap_4"]; // force refresh ldap server name display
[_settingsController.settingsReader indexPathForKey:@"ldap_5"]; // force refresh ldap server name display
[[_settingsController tableView] reloadData];
}
#pragma mark - IASKSettingsDelegate Functions
- (void)settingsViewControllerDidEnd:(IASKAppSettingsViewController *)sender {
@ -754,10 +798,15 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
// going to account: fill account specific info
if ([sender.file isEqualToString:@"Account"]) {
LOGI(@"Going editting account %@", sender.title);
LOGI(@"Going editing account %@", sender.title);
[settingsStore transformAccountToKeys:sender.title];
// coming back to default: if we were in account, we must synchronize account now
} else if ([sender.file isEqualToString:@"Root"]) {
} else if ([sender.file isEqualToString:@"Contacts"]) {
[settingsStore synchronize];
[self recomputeLdapLabelsAndSync];
} else if ([sender.file isEqualToString:@"LDAP"]) {
LOGI(@"Going editing LDAP config %@", sender.title);
[settingsStore transformLdapToKeys:sender.title];
} else if ([sender.file isEqualToString:@"Root"]) { // coming back to default: if we were in account, we must synchronize account now
[settingsStore synchronize];
[self recomputeAccountLabelsAndSync];
}
@ -987,6 +1036,32 @@ void update_hash_cbs(LinphoneAccountCreator *creator, LinphoneAccountCreatorStat
[self presentViewController:errView animated:YES completion:nil];
} else if ([key isEqual:@"send_db_button"]) {
[self sendEmailWithPrivacyAttachments];
} else if ([key isEqual:@"new_ldap_button"]) {
if (bctbx_list_size(linphone_core_get_ldap_list(LC)) < 5 ) {
linphone_core_add_ldap(LC, linphone_core_create_ldap(LC));
[self recomputeLdapLabelsAndSync];
}
} else if ([key isEqual:@"ldap_remove_button"]) {
UIAlertController *errView = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Warning", nil)
message:NSLocalizedString(@"Are you sure to want to remove your LDAP config?", nil)
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {}];
UIAlertAction* continueAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Yes", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[settingsStore removeLdap];
[self recomputeLdapLabelsAndSync];
[_settingsController.navigationController popViewControllerAnimated:NO];
}];
[errView addAction:defaultAction];
[errView addAction:continueAction];
[self presentViewController:errView animated:YES completion:nil];
}
}

View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Title</key>
<string>LDAP configs</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>new_ldap_button</string>
<key>Title</key>
<string>Add new LDAP config (5 max)</string>
<key>Type</key>
<string>IASKButtonSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_1</string>
<key>File</key>
<string>LDAP</string>
<key>Title</key>
<string>LDAP 1</string>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_2</string>
<key>File</key>
<string>LDAP</string>
<key>Title</key>
<string>LDAP 2</string>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_3</string>
<key>File</key>
<string>LDAP</string>
<key>Title</key>
<string>LDAP 3</string>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_4</string>
<key>File</key>
<string>LDAP</string>
<key>Title</key>
<string>LDAP 4</string>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_5</string>
<key>File</key>
<string>LDAP</string>
<key>Title</key>
<string>LDAP 5</string>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
</dict>
</array>
</dict>
</plist>

View file

@ -0,0 +1,318 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Enabled</string>
<key>Key</key>
<string>ldap_enabled</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Key</key>
<string>ldap_remove_button</string>
<key>Title</key>
<string>Delete this LDAP config</string>
<key>Type</key>
<string>IASKButtonSpecifier</string>
</dict>
<dict>
<key>Title</key>
<string>Connexion</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_server</string>
<key>Title</key>
<string>Server URL</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<false/>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_bind_dn</string>
<key>Title</key>
<string>Bind DN</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<false/>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<true/>
<key>Key</key>
<string>lda^p</string>
<key>KeyboardType</key>
<string>Alphabet</string>
<key>Title</key>
<string>Password</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
</dict>
<dict>
<key>DefaultValue</key>
<string>simple</string>
<key>Key</key>
<string>ldap_auth_method</string>
<key>Title</key>
<string>Authentication Method</string>
<key>Titles</key>
<array>
<string>Simple</string>
<string>Anonymous</string>
</array>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Values</key>
<array>
<string>simple</string>
<string>anonymous</string>
</array>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Use TLS</string>
<key>Key</key>
<string>ldap_tls_enabled</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>DefaultValue</key>
<string>simple</string>
<key>Key</key>
<string>ldap_certificates_verification_mode</string>
<key>Title</key>
<string>Certificate Verification</string>
<key>Titles</key>
<array>
<string>Auto</string>
<string>Enabled</string>
<string>Disabled</string>
</array>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Values</key>
<array>
<string>default</string>
<string>enabled</string>
<string>disabled</string>
</array>
</dict>
<dict>
<key>Title</key>
<string>Research</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_base_object</string>
<key>Title</key>
<string>Research Base</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<false/>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_filter</string>
<key>Title</key>
<string>Filter</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<false/>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_max_results</string>
<key>Title</key>
<string>Max results</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>KeyboardType</key>
<string>NumberPad</string>
<key>DefaultValue</key>
<integer>50</integer>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_timeout</string>
<key>Title</key>
<string>Timeout (seconds)</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>KeyboardType</key>
<string>NumberPad</string>
<key>DefaultValue</key>
<integer>5</integer>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_delay</string>
<key>Title</key>
<string>Delay (milliseconds)</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>KeyboardType</key>
<string>NumberPad</string>
<key>DefaultValue</key>
<integer>500</integer>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_min_chars</string>
<key>Title</key>
<string>Min chars</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>KeyboardType</key>
<string>NumberPad</string>
<key>DefaultValue</key>
<integer>3</integer>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Title</key>
<string>Analysis</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_name_attribute</string>
<key>Title</key>
<string>Name Attributes</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<false/>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_sip_attribute</string>
<key>Title</key>
<string>SIP Attributes</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<false/>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Key</key>
<string>ldap_sip_domain</string>
<key>Title</key>
<string>Domain</string>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
<key>DefaultValue</key>
<false/>
<key>IASKTextAlignment</key>
<string>IASKUITextAlignmentRight</string>
</dict>
<dict>
<key>Title</key>
<string>Miscellaneous</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Enabled</string>
<key>Key</key>
<string>ldap_logs_enabled</string>
<key>DefaultValue</key>
<true/>
</dict>
</array>
</dict>
</plist>

View file

@ -144,6 +144,16 @@
<key>Type</key>
<string>PSChildPaneSpecifier</string>
</dict>
<dict>
<key>Key</key>
<string>contacts_menu</string>
<key>File</key>
<string>Contacts</string>
<key>Title</key>
<string>Contacts</string>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
</dict>
<dict>
<key>File</key>
<string>Advanced</string>