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:
@@ -313,8 +313,8 @@ namespace Bit.Console
|
||||
break;
|
||||
}
|
||||
Con.Write("Type [{0}]: ", currentType);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
switch(input)
|
||||
{
|
||||
@@ -330,32 +330,32 @@ namespace Bit.Console
|
||||
}
|
||||
|
||||
Con.Write("Address [{0}]: ", config.Address);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.Address = input;
|
||||
}
|
||||
Con.Write("Port [{0}]: ", config.Port);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.Port = input;
|
||||
}
|
||||
Con.Write("Path [{0}]: ", config.Path);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.Path = input;
|
||||
}
|
||||
Con.Write("Username [{0}]: ", config.Username);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.Username = input;
|
||||
}
|
||||
Con.Write("Password: ");
|
||||
input = ReadSecureLine();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.Password = new EncryptedData(input);
|
||||
input = null;
|
||||
@@ -385,7 +385,8 @@ namespace Bit.Console
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -443,57 +444,63 @@ namespace Bit.Console
|
||||
string input;
|
||||
|
||||
Con.Write("Sync groups? [{0}]: ", config.SyncGroups ? "y" : "n");
|
||||
input = Con.ReadLine().Trim().ToLower();
|
||||
config.SyncGroups = input == "y" || input == "yes" || string.IsNullOrWhiteSpace(input);
|
||||
input = Con.ReadLine().ToLower();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.SyncGroups = input == "y" || input == "yes";
|
||||
}
|
||||
if(config.SyncGroups)
|
||||
{
|
||||
Con.Write("Group filter [{0}]: ", config.GroupFilter);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.GroupFilter = input;
|
||||
}
|
||||
Con.Write("Group name attribute [{0}]: ", config.GroupNameAttribute);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.GroupNameAttribute = input;
|
||||
}
|
||||
}
|
||||
Con.Write("Sync users? [{0}]: ", config.SyncUsers ? "y" : "n");
|
||||
input = Con.ReadLine().Trim().ToLower();
|
||||
config.SyncUsers = input == "y" || input == "yes" || string.IsNullOrWhiteSpace(input);
|
||||
input = Con.ReadLine().ToLower();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.SyncUsers = input == "y" || input == "yes";
|
||||
}
|
||||
if(config.SyncUsers)
|
||||
{
|
||||
Con.Write("User filter [{0}]: ", config.UserFilter);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.UserFilter = input;
|
||||
}
|
||||
Con.Write("User email attribute [{0}]: ", config.UserEmailAttribute);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.GroupNameAttribute = input;
|
||||
}
|
||||
}
|
||||
|
||||
Con.Write("Member Of Attribute [{0}]: ", config.MemberAttribute);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.MemberAttribute = input;
|
||||
}
|
||||
Con.Write("Creation Attribute [{0}]: ", config.CreationDateAttribute);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.CreationDateAttribute = input;
|
||||
}
|
||||
Con.Write("Changed Attribute [{0}]: ", config.RevisionDateAttribute);
|
||||
input = Con.ReadLine().Trim();
|
||||
if(!string.IsNullOrWhiteSpace(input))
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.RevisionDateAttribute = input;
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
<Compile Include="Services\TokenService.cs" />
|
||||
<Compile Include="Services\AuthService.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Utilities\Extensions.cs" />
|
||||
<Compile Include="Utilities\Sync.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Bit.Core.Enums
|
||||
public enum DirectoryType : byte
|
||||
{
|
||||
ActiveDirectory = 0,
|
||||
AzureActiveCirectory = 1,
|
||||
AzureActiveDirectory = 1,
|
||||
Other = 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Newtonsoft.Json;
|
||||
using Bit.Core.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.DirectoryServices;
|
||||
@@ -10,17 +11,38 @@ namespace Bit.Core.Models
|
||||
{
|
||||
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 UserFilter { get; set; } = "(&(objectClass=person))";
|
||||
public bool SyncGroups { 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 UserEmailAttribute { get; set; } = "mail";
|
||||
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 CreationDateAttribute { get; set; } = "whenCreated";
|
||||
public string RevisionDateAttribute { get; set; } = "whenChanged";
|
||||
public string CreationDateAttribute { get; set; }
|
||||
public string RevisionDateAttribute { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 string ApiBaseUrl { get; set; }
|
||||
@@ -175,6 +201,8 @@ namespace Bit.Core.Services
|
||||
public ServerConfiguration Server { get; set; }
|
||||
public SyncConfiguration Sync { get; set; }
|
||||
public Organization Organization { get; set; }
|
||||
public DateTime? LastGroupSyncDate { get; set; }
|
||||
public DateTime? LastUserSyncDate { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
24
src/Core/Utilities/Extensions.cs
Normal file
24
src/Core/Utilities/Extensions.cs
Normal 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'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,8 @@ namespace Bit.Core.Utilities
|
||||
};
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
List<GroupEntry> groups = null;
|
||||
if(SettingsService.Instance.Sync.SyncGroups)
|
||||
{
|
||||
@@ -58,6 +60,16 @@ namespace Bit.Core.Utilities
|
||||
var response = await ApiService.Instance.PostImportAsync(request);
|
||||
if(response.Succeeded)
|
||||
{
|
||||
if(SettingsService.Instance.Sync.SyncGroups)
|
||||
{
|
||||
SettingsService.Instance.LastGroupSyncDate = now;
|
||||
}
|
||||
|
||||
if(SettingsService.Instance.Sync.SyncUsers)
|
||||
{
|
||||
SettingsService.Instance.LastUserSyncDate = now;
|
||||
}
|
||||
|
||||
return new SyncResult
|
||||
{
|
||||
Success = true,
|
||||
@@ -100,6 +112,16 @@ namespace Bit.Core.Utilities
|
||||
var entry = SettingsService.Instance.Server.GetDirectoryEntry();
|
||||
var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.GroupFilter) ? null :
|
||||
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 result = searcher.FindAll();
|
||||
|
||||
@@ -180,6 +202,16 @@ namespace Bit.Core.Utilities
|
||||
var entry = SettingsService.Instance.Server.GetDirectoryEntry();
|
||||
var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserFilter) ? null :
|
||||
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 result = searcher.FindAll();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user