mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-15 07:43:27 +00:00
separate ldap config from sync
This commit is contained in:
@@ -535,7 +535,7 @@ namespace Bit.Console
|
||||
}
|
||||
if(parameters.ContainsKey("gn"))
|
||||
{
|
||||
config.GroupNameAttribute = parameters["gn"];
|
||||
config.Ldap.GroupNameAttribute = parameters["gn"];
|
||||
}
|
||||
|
||||
if(parameters.ContainsKey("uf"))
|
||||
@@ -544,34 +544,34 @@ namespace Bit.Console
|
||||
}
|
||||
if(parameters.ContainsKey("ue"))
|
||||
{
|
||||
config.UserEmailAttribute = parameters["ue"];
|
||||
config.Ldap.UserEmailAttribute = parameters["ue"];
|
||||
}
|
||||
|
||||
if(parameters.ContainsKey("m"))
|
||||
{
|
||||
config.MemberAttribute = parameters["m"];
|
||||
config.Ldap.MemberAttribute = parameters["m"];
|
||||
}
|
||||
|
||||
config.EmailPrefixSuffix = parameters.ContainsKey("ps");
|
||||
config.Ldap.EmailPrefixSuffix = parameters.ContainsKey("ps");
|
||||
|
||||
if(parameters.ContainsKey("ep"))
|
||||
{
|
||||
config.UserEmailPrefixAttribute = parameters["ep"];
|
||||
config.Ldap.UserEmailPrefixAttribute = parameters["ep"];
|
||||
}
|
||||
|
||||
if(parameters.ContainsKey("es"))
|
||||
{
|
||||
config.UserEmailSuffix = parameters["es"];
|
||||
config.Ldap.UserEmailSuffix = parameters["es"];
|
||||
}
|
||||
|
||||
if(parameters.ContainsKey("c"))
|
||||
{
|
||||
config.CreationDateAttribute = parameters["c"];
|
||||
config.Ldap.CreationDateAttribute = parameters["c"];
|
||||
}
|
||||
|
||||
if(parameters.ContainsKey("r"))
|
||||
{
|
||||
config.RevisionDateAttribute = parameters["r"];
|
||||
config.Ldap.RevisionDateAttribute = parameters["r"];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -588,19 +588,32 @@ namespace Bit.Console
|
||||
if(config.SyncGroups &&
|
||||
Core.Services.SettingsService.Instance.Server.Type != Core.Enums.DirectoryType.AzureActiveDirectory)
|
||||
{
|
||||
Con.Write("Group object class [{0}]: ", config.Ldap.GroupObjectClass);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.Ldap.GroupObjectClass = input;
|
||||
}
|
||||
Con.Write("Group filter [{0}]: ", config.GroupFilter);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.GroupFilter = input;
|
||||
}
|
||||
Con.Write("Group name attribute [{0}]: ", config.GroupNameAttribute);
|
||||
Con.Write("Group name attribute [{0}]: ", config.Ldap.GroupNameAttribute);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.GroupNameAttribute = input;
|
||||
config.Ldap.GroupNameAttribute = input;
|
||||
}
|
||||
}
|
||||
Con.Write("Group path [{0}]: ", config.Ldap.GroupPath);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.Ldap.GroupPath = input;
|
||||
}
|
||||
|
||||
Con.Write("Sync users? [{0}]: ", config.SyncUsers ? "y" : "n");
|
||||
input = Con.ReadLine().ToLower();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
@@ -610,39 +623,51 @@ namespace Bit.Console
|
||||
if(config.SyncUsers &&
|
||||
Core.Services.SettingsService.Instance.Server.Type != Core.Enums.DirectoryType.AzureActiveDirectory)
|
||||
{
|
||||
Con.Write("User filter [{0}]: ", config.UserFilter);
|
||||
Con.Write("User path [{0}]: ", config.Ldap.UserPath);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.UserFilter = input;
|
||||
config.Ldap.GroupPath = input;
|
||||
}
|
||||
Con.Write("User email attribute [{0}]: ", config.UserEmailAttribute);
|
||||
Con.Write("User object class [{0}]: ", config.Ldap.UserObjectClass);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.GroupNameAttribute = input;
|
||||
config.Ldap.GroupObjectClass = input;
|
||||
}
|
||||
Con.Write("User email attribute [{0}]: ", config.Ldap.UserEmailAttribute);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.Ldap.GroupNameAttribute = input;
|
||||
}
|
||||
}
|
||||
Con.Write("User filter [{0}]: ", config.UserFilter);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.UserFilter = input;
|
||||
}
|
||||
|
||||
if(Core.Services.SettingsService.Instance.Server.Type != Core.Enums.DirectoryType.AzureActiveDirectory)
|
||||
{
|
||||
Con.Write("Member Of Attribute [{0}]: ", config.MemberAttribute);
|
||||
Con.Write("Member Of Attribute [{0}]: ", config.Ldap.MemberAttribute);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.MemberAttribute = input;
|
||||
config.Ldap.MemberAttribute = input;
|
||||
}
|
||||
Con.Write("Creation Attribute [{0}]: ", config.CreationDateAttribute);
|
||||
Con.Write("Creation Attribute [{0}]: ", config.Ldap.CreationDateAttribute);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.CreationDateAttribute = input;
|
||||
config.Ldap.CreationDateAttribute = input;
|
||||
}
|
||||
Con.Write("Changed Attribute [{0}]: ", config.RevisionDateAttribute);
|
||||
Con.Write("Changed Attribute [{0}]: ", config.Ldap.RevisionDateAttribute);
|
||||
input = Con.ReadLine();
|
||||
if(!string.IsNullOrEmpty(input))
|
||||
{
|
||||
config.RevisionDateAttribute = input;
|
||||
config.Ldap.RevisionDateAttribute = input;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,18 +18,15 @@ namespace Bit.Core.Models
|
||||
switch(type)
|
||||
{
|
||||
case DirectoryType.ActiveDirectory:
|
||||
CreationDateAttribute = "whenCreated";
|
||||
RevisionDateAttribute = "whenChanged";
|
||||
UserEmailPrefixAttribute = "sAMAccountName";
|
||||
Ldap.CreationDateAttribute = "whenCreated";
|
||||
Ldap.RevisionDateAttribute = "whenChanged";
|
||||
Ldap.UserEmailPrefixAttribute = "sAMAccountName";
|
||||
Ldap.UserPath = "Users";
|
||||
Ldap.GroupPath = "Users";
|
||||
break;
|
||||
case DirectoryType.AzureActiveDirectory:
|
||||
GroupFilter = null;
|
||||
UserFilter = null;
|
||||
MemberAttribute = null;
|
||||
GroupNameAttribute = null;
|
||||
UserEmailAttribute = null;
|
||||
UserEmailPrefixAttribute = null;
|
||||
UserEmailSuffix = null;
|
||||
break;
|
||||
case DirectoryType.Other:
|
||||
IntervalMinutes = 60;
|
||||
@@ -39,18 +36,27 @@ namespace Bit.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
public string GroupFilter { get; set; } = "(&(objectClass=group))";
|
||||
public string UserFilter { get; set; } = "(&(objectClass=person))";
|
||||
public string GroupFilter { get; set; }
|
||||
public string UserFilter { get; set; }
|
||||
public bool SyncGroups { get; set; } = true;
|
||||
public bool SyncUsers { get; set; } = true;
|
||||
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; } = "cn";
|
||||
public string UserEmailSuffix { get; set; } = "@companyname.com";
|
||||
public string CreationDateAttribute { get; set; }
|
||||
public string RevisionDateAttribute { get; set; }
|
||||
public int IntervalMinutes { get; set; } = 5;
|
||||
public LdapSyncConfiguration Ldap { get; set; } = new LdapSyncConfiguration();
|
||||
|
||||
public class LdapSyncConfiguration
|
||||
{
|
||||
public string UserPath { get; set; }
|
||||
public string GroupPath { get; set; }
|
||||
public string UserObjectClass { get; set; } = "person";
|
||||
public string GroupObjectClass { get; set; } = "group";
|
||||
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; } = "cn";
|
||||
public string UserEmailSuffix { get; set; } = "@companyname.com";
|
||||
public string CreationDateAttribute { get; set; }
|
||||
public string RevisionDateAttribute { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,19 +85,13 @@ namespace Bit.Core.Services
|
||||
|
||||
var entry = SettingsService.Instance.Server.Ldap.GetDirectoryEntry();
|
||||
|
||||
string originalFilter;
|
||||
var filter = originalFilter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.GroupFilter) ? null :
|
||||
SettingsService.Instance.Sync.GroupFilter;
|
||||
var originalFilter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.GroupObjectClass,
|
||||
SettingsService.Instance.Sync.GroupFilter);
|
||||
|
||||
var searchSinceRevision = !force && !string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.RevisionDateAttribute) &&
|
||||
SettingsService.Instance.LastGroupSyncDate.HasValue;
|
||||
if(searchSinceRevision)
|
||||
{
|
||||
filter = string.Format("(&{0}({1}>={2}))",
|
||||
filter,
|
||||
SettingsService.Instance.Sync.RevisionDateAttribute,
|
||||
SettingsService.Instance.LastGroupSyncDate.Value.ToGeneralizedTimeUTC());
|
||||
}
|
||||
var filter = originalFilter;
|
||||
var revisionFilter = BuildRevisionFilter(filter, force, SettingsService.Instance.LastGroupSyncDate);
|
||||
var searchSinceRevision = filter != revisionFilter;
|
||||
filter = revisionFilter;
|
||||
|
||||
var searcher = new DirectorySearcher(entry, filter);
|
||||
var result = searcher.FindAll();
|
||||
@@ -118,8 +112,8 @@ namespace Bit.Core.Services
|
||||
result = searcher.FindAll();
|
||||
}
|
||||
|
||||
var userFilter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserFilter) ? null :
|
||||
SettingsService.Instance.Sync.UserFilter;
|
||||
var userFilter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.UserObjectClass,
|
||||
SettingsService.Instance.Sync.UserFilter);
|
||||
var userSearcher = new DirectorySearcher(entry, userFilter);
|
||||
var userResult = userSearcher.FindAll();
|
||||
|
||||
@@ -181,10 +175,10 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
// Name
|
||||
if(item.Properties.Contains(SettingsService.Instance.Sync.GroupNameAttribute) &&
|
||||
item.Properties[SettingsService.Instance.Sync.GroupNameAttribute].Count > 0)
|
||||
if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.GroupNameAttribute) &&
|
||||
item.Properties[SettingsService.Instance.Sync.Ldap.GroupNameAttribute].Count > 0)
|
||||
{
|
||||
group.Name = item.Properties[SettingsService.Instance.Sync.GroupNameAttribute][0].ToString();
|
||||
group.Name = item.Properties[SettingsService.Instance.Sync.Ldap.GroupNameAttribute][0].ToString();
|
||||
}
|
||||
else if(item.Properties.Contains("cn") && item.Properties["cn"].Count > 0)
|
||||
{
|
||||
@@ -196,14 +190,14 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
// Dates
|
||||
group.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.CreationDateAttribute);
|
||||
group.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.RevisionDateAttribute);
|
||||
group.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.CreationDateAttribute);
|
||||
group.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute);
|
||||
|
||||
// Members
|
||||
if(item.Properties.Contains(SettingsService.Instance.Sync.MemberAttribute) &&
|
||||
item.Properties[SettingsService.Instance.Sync.MemberAttribute].Count > 0)
|
||||
if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.MemberAttribute) &&
|
||||
item.Properties[SettingsService.Instance.Sync.Ldap.MemberAttribute].Count > 0)
|
||||
{
|
||||
foreach(var member in item.Properties[SettingsService.Instance.Sync.MemberAttribute])
|
||||
foreach(var member in item.Properties[SettingsService.Instance.Sync.Ldap.MemberAttribute])
|
||||
{
|
||||
var memberDn = member.ToString();
|
||||
if(userIndex.ContainsKey(memberDn) && !group.UserMemberExternalIds.Contains(userIndex[memberDn]))
|
||||
@@ -243,17 +237,9 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
var entry = SettingsService.Instance.Server.Ldap.GetDirectoryEntry();
|
||||
var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserFilter) ? null :
|
||||
SettingsService.Instance.Sync.UserFilter;
|
||||
|
||||
if(!force && !string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.RevisionDateAttribute) &&
|
||||
SettingsService.Instance.LastUserSyncDate.HasValue)
|
||||
{
|
||||
filter = string.Format("(&{0}({1}>={2}))",
|
||||
filter,
|
||||
SettingsService.Instance.Sync.RevisionDateAttribute,
|
||||
SettingsService.Instance.LastUserSyncDate.Value.ToGeneralizedTimeUTC());
|
||||
}
|
||||
var filter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.UserObjectClass,
|
||||
SettingsService.Instance.Sync.UserFilter);
|
||||
filter = BuildRevisionFilter(filter, force, SettingsService.Instance.LastUserSyncDate);
|
||||
|
||||
var searcher = new DirectorySearcher(entry, filter);
|
||||
var result = searcher.FindAll();
|
||||
@@ -293,6 +279,36 @@ namespace Bit.Core.Services
|
||||
return Task.FromResult(users);
|
||||
}
|
||||
|
||||
private static string BuildBaseFilter(string objectClass, string subFilter)
|
||||
{
|
||||
var filter = BuildObjectClassFilter(objectClass);
|
||||
if(!string.IsNullOrWhiteSpace(subFilter))
|
||||
{
|
||||
filter = string.Format("(&{0}{1})", filter, subFilter);
|
||||
}
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
private static string BuildObjectClassFilter(string objectClass)
|
||||
{
|
||||
return string.Format("(&(objectClass={0}))", objectClass);
|
||||
}
|
||||
|
||||
private static string BuildRevisionFilter(string baseFilter, bool force, DateTime? lastRevisionDate)
|
||||
{
|
||||
if(!force && lastRevisionDate.HasValue &&
|
||||
!string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute))
|
||||
{
|
||||
baseFilter = string.Format("(&{0}({1}>={2}))",
|
||||
baseFilter,
|
||||
SettingsService.Instance.Sync.Ldap.RevisionDateAttribute,
|
||||
lastRevisionDate.Value.ToGeneralizedTimeUTC());
|
||||
}
|
||||
|
||||
return baseFilter;
|
||||
}
|
||||
|
||||
private static UserEntry BuildUser(SearchResult item, bool deleted)
|
||||
{
|
||||
var user = new UserEntry
|
||||
@@ -319,19 +335,19 @@ namespace Bit.Core.Services
|
||||
user.Disabled = EntryDisabled(item);
|
||||
|
||||
// Email
|
||||
if(SettingsService.Instance.Sync.EmailPrefixSuffix &&
|
||||
item.Properties.Contains(SettingsService.Instance.Sync.UserEmailPrefixAttribute) &&
|
||||
item.Properties[SettingsService.Instance.Sync.UserEmailPrefixAttribute].Count > 0 &&
|
||||
!string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.UserEmailSuffix))
|
||||
if(SettingsService.Instance.Sync.Ldap.EmailPrefixSuffix &&
|
||||
item.Properties.Contains(SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute) &&
|
||||
item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute].Count > 0 &&
|
||||
!string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.Ldap.UserEmailSuffix))
|
||||
{
|
||||
user.Email = string.Concat(
|
||||
item.Properties[SettingsService.Instance.Sync.UserEmailPrefixAttribute][0].ToString(),
|
||||
SettingsService.Instance.Sync.UserEmailSuffix).ToLowerInvariant();
|
||||
item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute][0].ToString(),
|
||||
SettingsService.Instance.Sync.Ldap.UserEmailSuffix).ToLowerInvariant();
|
||||
}
|
||||
else if(item.Properties.Contains(SettingsService.Instance.Sync.UserEmailAttribute) &&
|
||||
item.Properties[SettingsService.Instance.Sync.UserEmailAttribute].Count > 0)
|
||||
else if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.UserEmailAttribute) &&
|
||||
item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailAttribute].Count > 0)
|
||||
{
|
||||
user.Email = item.Properties[SettingsService.Instance.Sync.UserEmailAttribute][0]
|
||||
user.Email = item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailAttribute][0]
|
||||
.ToString()
|
||||
.ToLowerInvariant();
|
||||
}
|
||||
@@ -341,8 +357,8 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
// Dates
|
||||
user.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.CreationDateAttribute);
|
||||
user.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.RevisionDateAttribute);
|
||||
user.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.CreationDateAttribute);
|
||||
user.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user