1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-15 15:53:41 +00:00

revision date filter. allow clearing config values

This commit is contained in:
Kyle Spearrin
2017-05-13 22:47:22 -04:00
parent e2a443640b
commit ca30ab61aa
7 changed files with 150 additions and 36 deletions

View File

@@ -313,8 +313,8 @@ namespace Bit.Console
break; break;
} }
Con.Write("Type [{0}]: ", currentType); Con.Write("Type [{0}]: ", currentType);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
switch(input) switch(input)
{ {
@@ -330,32 +330,32 @@ namespace Bit.Console
} }
Con.Write("Address [{0}]: ", config.Address); Con.Write("Address [{0}]: ", config.Address);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.Address = input; config.Address = input;
} }
Con.Write("Port [{0}]: ", config.Port); Con.Write("Port [{0}]: ", config.Port);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.Port = input; config.Port = input;
} }
Con.Write("Path [{0}]: ", config.Path); Con.Write("Path [{0}]: ", config.Path);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.Path = input; config.Path = input;
} }
Con.Write("Username [{0}]: ", config.Username); Con.Write("Username [{0}]: ", config.Username);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.Username = input; config.Username = input;
} }
Con.Write("Password: "); Con.Write("Password: ");
input = ReadSecureLine(); input = ReadSecureLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.Password = new EncryptedData(input); config.Password = new EncryptedData(input);
input = null; input = null;
@@ -385,7 +385,8 @@ namespace Bit.Console
private static Task ConfigSyncAsync() private static Task ConfigSyncAsync()
{ {
var config = Core.Services.SettingsService.Instance.Sync ?? new SyncConfiguration(); var config = Core.Services.SettingsService.Instance.Sync ??
new SyncConfiguration(Core.Services.SettingsService.Instance.Server.Type);
if(_usingArgs) if(_usingArgs)
{ {
@@ -443,57 +444,63 @@ namespace Bit.Console
string input; string input;
Con.Write("Sync groups? [{0}]: ", config.SyncGroups ? "y" : "n"); Con.Write("Sync groups? [{0}]: ", config.SyncGroups ? "y" : "n");
input = Con.ReadLine().Trim().ToLower(); input = Con.ReadLine().ToLower();
config.SyncGroups = input == "y" || input == "yes" || string.IsNullOrWhiteSpace(input); if(!string.IsNullOrEmpty(input))
{
config.SyncGroups = input == "y" || input == "yes";
}
if(config.SyncGroups) if(config.SyncGroups)
{ {
Con.Write("Group filter [{0}]: ", config.GroupFilter); Con.Write("Group filter [{0}]: ", config.GroupFilter);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.GroupFilter = input; config.GroupFilter = input;
} }
Con.Write("Group name attribute [{0}]: ", config.GroupNameAttribute); Con.Write("Group name attribute [{0}]: ", config.GroupNameAttribute);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.GroupNameAttribute = input; config.GroupNameAttribute = input;
} }
} }
Con.Write("Sync users? [{0}]: ", config.SyncUsers ? "y" : "n"); Con.Write("Sync users? [{0}]: ", config.SyncUsers ? "y" : "n");
input = Con.ReadLine().Trim().ToLower(); input = Con.ReadLine().ToLower();
config.SyncUsers = input == "y" || input == "yes" || string.IsNullOrWhiteSpace(input); if(!string.IsNullOrEmpty(input))
{
config.SyncUsers = input == "y" || input == "yes";
}
if(config.SyncUsers) if(config.SyncUsers)
{ {
Con.Write("User filter [{0}]: ", config.UserFilter); Con.Write("User filter [{0}]: ", config.UserFilter);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.UserFilter = input; config.UserFilter = input;
} }
Con.Write("User email attribute [{0}]: ", config.UserEmailAttribute); Con.Write("User email attribute [{0}]: ", config.UserEmailAttribute);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.GroupNameAttribute = input; config.GroupNameAttribute = input;
} }
} }
Con.Write("Member Of Attribute [{0}]: ", config.MemberAttribute); Con.Write("Member Of Attribute [{0}]: ", config.MemberAttribute);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.MemberAttribute = input; config.MemberAttribute = input;
} }
Con.Write("Creation Attribute [{0}]: ", config.CreationDateAttribute); Con.Write("Creation Attribute [{0}]: ", config.CreationDateAttribute);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.CreationDateAttribute = input; config.CreationDateAttribute = input;
} }
Con.Write("Changed Attribute [{0}]: ", config.RevisionDateAttribute); Con.Write("Changed Attribute [{0}]: ", config.RevisionDateAttribute);
input = Con.ReadLine().Trim(); input = Con.ReadLine();
if(!string.IsNullOrWhiteSpace(input)) if(!string.IsNullOrEmpty(input))
{ {
config.RevisionDateAttribute = input; config.RevisionDateAttribute = input;
} }

View File

@@ -73,6 +73,7 @@
<Compile Include="Services\TokenService.cs" /> <Compile Include="Services\TokenService.cs" />
<Compile Include="Services\AuthService.cs" /> <Compile Include="Services\AuthService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\Sync.cs" /> <Compile Include="Utilities\Sync.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -9,7 +9,7 @@ namespace Bit.Core.Enums
public enum DirectoryType : byte public enum DirectoryType : byte
{ {
ActiveDirectory = 0, ActiveDirectory = 0,
AzureActiveCirectory = 1, AzureActiveDirectory = 1,
Other = 2 Other = 2
} }
} }

View File

@@ -1,4 +1,5 @@
using Newtonsoft.Json; using Bit.Core.Enums;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.DirectoryServices; using System.DirectoryServices;
@@ -10,17 +11,38 @@ namespace Bit.Core.Models
{ {
public class SyncConfiguration public class SyncConfiguration
{ {
public SyncConfiguration() { }
public SyncConfiguration(DirectoryType type)
{
switch(type)
{
case DirectoryType.ActiveDirectory:
MemberAttribute = "memberOf";
CreationDateAttribute = "whenCreated";
RevisionDateAttribute = "whenChanged";
UserEmailPrefixAttribute = "sAMAccountName";
break;
case DirectoryType.AzureActiveDirectory:
break;
case DirectoryType.Other:
break;
default:
break;
}
}
public string GroupFilter { get; set; } = "(&(objectClass=group))"; public string GroupFilter { get; set; } = "(&(objectClass=group))";
public string UserFilter { get; set; } = "(&(objectClass=person))"; public string UserFilter { get; set; } = "(&(objectClass=person))";
public bool SyncGroups { get; set; } = true; public bool SyncGroups { get; set; } = true;
public bool SyncUsers { get; set; } = true; public bool SyncUsers { get; set; } = true;
public string MemberAttribute { get; set; } = "memberOf"; public string MemberAttribute { get; set; } = "member";
public string GroupNameAttribute { get; set; } = "name"; public string GroupNameAttribute { get; set; } = "name";
public string UserEmailAttribute { get; set; } = "mail"; public string UserEmailAttribute { get; set; } = "mail";
public bool EmailPrefixSuffix { get; set; } = false; public bool EmailPrefixSuffix { get; set; } = false;
public string UserEmailPrefixAttribute { get; set; } = "sAMAccountName"; public string UserEmailPrefixAttribute { get; set; } = "cn";
public string UserEmailSuffix { get; set; } = "@companyname.com"; public string UserEmailSuffix { get; set; } = "@companyname.com";
public string CreationDateAttribute { get; set; } = "whenCreated"; public string CreationDateAttribute { get; set; }
public string RevisionDateAttribute { get; set; } = "whenChanged"; public string RevisionDateAttribute { get; set; }
} }
} }

View File

@@ -166,6 +166,32 @@ namespace Bit.Core.Services
} }
} }
public DateTime? LastGroupSyncDate
{
get
{
return Settings.LastGroupSyncDate;
}
set
{
Settings.LastGroupSyncDate = value;
SaveSettings();
}
}
public DateTime? LastUserSyncDate
{
get
{
return Settings.LastUserSyncDate;
}
set
{
Settings.LastUserSyncDate = value;
SaveSettings();
}
}
public class SettingsModel public class SettingsModel
{ {
public string ApiBaseUrl { get; set; } public string ApiBaseUrl { get; set; }
@@ -175,6 +201,8 @@ namespace Bit.Core.Services
public ServerConfiguration Server { get; set; } public ServerConfiguration Server { get; set; }
public SyncConfiguration Sync { get; set; } public SyncConfiguration Sync { get; set; }
public Organization Organization { get; set; } public Organization Organization { get; set; }
public DateTime? LastGroupSyncDate { get; set; }
public DateTime? LastUserSyncDate { get; set; }
} }
} }
} }

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Bit.Core.Utilities
{
public static class Extensions
{
private const string GeneralizedTimeFormat = "yyyyMMddHHmmss.f'Z'";
public static DateTime ToDateTime(this string generalizedTimeString)
{
return DateTime.ParseExact(generalizedTimeString, GeneralizedTimeFormat, CultureInfo.InvariantCulture);
}
public static string ToGeneralizedTimeUTC(this DateTime date)
{
return date.ToString("yyyyMMddHHmmss.f'Z'");
}
}
}

View File

@@ -40,6 +40,8 @@ namespace Bit.Core.Utilities
}; };
} }
var now = DateTime.UtcNow;
List<GroupEntry> groups = null; List<GroupEntry> groups = null;
if(SettingsService.Instance.Sync.SyncGroups) if(SettingsService.Instance.Sync.SyncGroups)
{ {
@@ -58,6 +60,16 @@ namespace Bit.Core.Utilities
var response = await ApiService.Instance.PostImportAsync(request); var response = await ApiService.Instance.PostImportAsync(request);
if(response.Succeeded) if(response.Succeeded)
{ {
if(SettingsService.Instance.Sync.SyncGroups)
{
SettingsService.Instance.LastGroupSyncDate = now;
}
if(SettingsService.Instance.Sync.SyncUsers)
{
SettingsService.Instance.LastUserSyncDate = now;
}
return new SyncResult return new SyncResult
{ {
Success = true, Success = true,
@@ -100,6 +112,16 @@ namespace Bit.Core.Utilities
var entry = SettingsService.Instance.Server.GetDirectoryEntry(); var entry = SettingsService.Instance.Server.GetDirectoryEntry();
var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.GroupFilter) ? null : var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.GroupFilter) ? null :
SettingsService.Instance.Sync.GroupFilter; SettingsService.Instance.Sync.GroupFilter;
if(!string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.RevisionDateAttribute) &&
SettingsService.Instance.LastGroupSyncDate.HasValue)
{
filter = string.Format("(&{0}({1}>{2}))",
filter != null ? string.Format("({0})", filter) : string.Empty,
SettingsService.Instance.Sync.RevisionDateAttribute,
SettingsService.Instance.LastGroupSyncDate.Value.ToGeneralizedTimeUTC());
}
var searcher = new DirectorySearcher(entry, filter); var searcher = new DirectorySearcher(entry, filter);
var result = searcher.FindAll(); var result = searcher.FindAll();
@@ -180,6 +202,16 @@ namespace Bit.Core.Utilities
var entry = SettingsService.Instance.Server.GetDirectoryEntry(); var entry = SettingsService.Instance.Server.GetDirectoryEntry();
var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserFilter) ? null : var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserFilter) ? null :
SettingsService.Instance.Sync.UserFilter; SettingsService.Instance.Sync.UserFilter;
if(!string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.RevisionDateAttribute) &&
SettingsService.Instance.LastUserSyncDate.HasValue)
{
filter = string.Format("(&{0}({1}>{2}))",
filter != null ? string.Format("({0})", filter) : string.Empty,
SettingsService.Instance.Sync.RevisionDateAttribute,
SettingsService.Instance.LastUserSyncDate.Value.ToGeneralizedTimeUTC());
}
var searcher = new DirectorySearcher(entry, filter); var searcher = new DirectorySearcher(entry, filter);
var result = searcher.FindAll(); var result = searcher.FindAll();