From 9e0ca53654d21df395d8b567dbd9a3e42b40e1e7 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Sat, 13 May 2017 15:06:02 -0400 Subject: [PATCH] import api --- src/Core/Core.csproj | 1 + src/Core/Models/ImportRequest.cs | 42 ++++++++++++ src/Core/Services/ApiService.cs | 35 ++++++++++ src/Core/Utilities/Sync.cs | 107 ++++++++++++++++--------------- 4 files changed, 133 insertions(+), 52 deletions(-) create mode 100644 src/Core/Models/ImportRequest.cs diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 41853de8..f7b1b237 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -52,6 +52,7 @@ + diff --git a/src/Core/Models/ImportRequest.cs b/src/Core/Models/ImportRequest.cs new file mode 100644 index 00000000..619ad841 --- /dev/null +++ b/src/Core/Models/ImportRequest.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Bit.Core.Models +{ + public class ImportRequest + { + public ImportRequest(List groups, List users) + { + Groups = groups.Select(g => new Group(g)).ToArray(); + Users = users.Select(u => new User(u)).ToArray(); + } + + public Group[] Groups { get; set; } + public User[] Users { get; set; } + + public class Group + { + public Group(GroupEntry entry) + { + Name = entry.Name; + ExternalId = entry.DistinguishedName; + } + + public string Name { get; set; } + public string ExternalId { get; set; } + } + + public class User + { + public User(UserEntry entry) + { + Email = entry.Email; + ExternalGroupIds = entry.Groups; + } + + public string Email { get; set; } + public IEnumerable ExternalGroupIds { get; set; } + } + } + +} diff --git a/src/Core/Services/ApiService.cs b/src/Core/Services/ApiService.cs index c710c832..a8b532c4 100644 --- a/src/Core/Services/ApiService.cs +++ b/src/Core/Services/ApiService.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Net; using System.Net.Http; +using System.Text; using System.Threading.Tasks; namespace Bit.Core.Services @@ -85,6 +86,40 @@ namespace Bit.Core.Services } } + public virtual async Task PostImportAsync(ImportRequest requestObj) + { + var tokenStateResponse = await HandleTokenStateAsync(); + if(!tokenStateResponse.Succeeded) + { + return tokenStateResponse; + } + + var stringContent = JsonConvert.SerializeObject(requestObj); + var requestMessage = new HttpRequestMessage + { + Method = HttpMethod.Post, + RequestUri = new Uri(ApiClient.BaseAddress, "import"), // TODO: org id + Content = new StringContent(stringContent, Encoding.UTF8, "application/json"), + }; + + requestMessage.Headers.Add("Authorization", $"Bearer3 {TokenService.Instance.AccessToken}"); + + try + { + var response = await ApiClient.SendAsync(requestMessage).ConfigureAwait(false); + if(!response.IsSuccessStatusCode) + { + return await HandleErrorAsync(response).ConfigureAwait(false); + } + + return ApiResult.Success(response.StatusCode); + } + catch + { + return HandledWebException(); + } + } + protected ApiResult HandledWebException() { return ApiResult.Failed(HttpStatusCode.BadGateway, diff --git a/src/Core/Utilities/Sync.cs b/src/Core/Utilities/Sync.cs index 94cd433a..442d5a78 100644 --- a/src/Core/Utilities/Sync.cs +++ b/src/Core/Utilities/Sync.cs @@ -1,36 +1,56 @@ using Bit.Core.Models; +using Bit.Core.Services; using System; using System.Collections; using System.Collections.Generic; using System.DirectoryServices; using System.Linq; -using System.Text; using System.Threading.Tasks; namespace Bit.Core.Utilities { public static class Sync { - public static Task> SyncGroupsAsync() + public static async Task SyncAllAsync() { - if(!Services.SettingsService.Instance.Server.SyncGroups) + List groups = null; + if(SettingsService.Instance.Server.SyncGroups) + { + groups = await GetGroupsAsync(); + } + + List users = null; + if(SettingsService.Instance.Server.SyncUsers) + { + users = await GetUsersAsync(); + } + + FlattenGroupsToUsers(groups, null, groups, users); + + var request = new ImportRequest(groups, users); + await ApiService.Instance.PostImportAsync(request); + } + + private static Task> GetGroupsAsync() + { + if(!SettingsService.Instance.Server.SyncGroups) { throw new ApplicationException("Not configured to sync groups."); } - if(Services.SettingsService.Instance.Server == null) + if(SettingsService.Instance.Server == null) { throw new ApplicationException("No configuration for directory server."); } - if(!Services.AuthService.Instance.Authenticated) + if(!AuthService.Instance.Authenticated) { throw new ApplicationException("Not authenticated."); } - var entry = Services.SettingsService.Instance.Server.GetDirectoryEntry(); - var filter = string.IsNullOrWhiteSpace(Services.SettingsService.Instance.Server.GroupFilter) ? null : - Services.SettingsService.Instance.Server.GroupFilter; + var entry = SettingsService.Instance.Server.GetDirectoryEntry(); + var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Server.GroupFilter) ? null : + SettingsService.Instance.Server.GroupFilter; var searcher = new DirectorySearcher(entry, filter); var result = searcher.FindAll(); @@ -48,10 +68,10 @@ namespace Bit.Core.Utilities } // Name - if(item.Properties.Contains(Services.SettingsService.Instance.Server.GroupNameAttribute) && - item.Properties[Services.SettingsService.Instance.Server.GroupNameAttribute].Count > 0) + if(item.Properties.Contains(SettingsService.Instance.Server.GroupNameAttribute) && + item.Properties[SettingsService.Instance.Server.GroupNameAttribute].Count > 0) { - group.Name = item.Properties[Services.SettingsService.Instance.Server.GroupNameAttribute][0].ToString(); + group.Name = item.Properties[SettingsService.Instance.Server.GroupNameAttribute][0].ToString(); } else if(item.Properties.Contains("cn") && item.Properties["cn"].Count > 0) { @@ -63,14 +83,14 @@ namespace Bit.Core.Utilities } // Dates - group.CreationDate = ParseDate(item.Properties, Services.SettingsService.Instance.Server.CreationDateAttribute); - group.RevisionDate = ParseDate(item.Properties, Services.SettingsService.Instance.Server.RevisionDateAttribute); + group.CreationDate = ParseDate(item.Properties, SettingsService.Instance.Server.CreationDateAttribute); + group.RevisionDate = ParseDate(item.Properties, SettingsService.Instance.Server.RevisionDateAttribute); // Members - if(item.Properties.Contains(Services.SettingsService.Instance.Server.MemberAttribute) && - item.Properties[Services.SettingsService.Instance.Server.MemberAttribute].Count > 0) + if(item.Properties.Contains(SettingsService.Instance.Server.MemberAttribute) && + item.Properties[SettingsService.Instance.Server.MemberAttribute].Count > 0) { - foreach(var member in item.Properties[Services.SettingsService.Instance.Server.MemberAttribute]) + foreach(var member in item.Properties[SettingsService.Instance.Server.MemberAttribute]) { var memberDn = member.ToString(); if(!group.Members.Contains(memberDn)) @@ -86,26 +106,26 @@ namespace Bit.Core.Utilities return Task.FromResult(groups); } - public static Task> SyncUsersAsync() + private static Task> GetUsersAsync() { - if(!Services.SettingsService.Instance.Server.SyncUsers) + if(!SettingsService.Instance.Server.SyncUsers) { throw new ApplicationException("Not configured to sync users."); } - if(Services.SettingsService.Instance.Server == null) + if(SettingsService.Instance.Server == null) { throw new ApplicationException("No configuration for directory server."); } - if(!Services.AuthService.Instance.Authenticated) + if(!AuthService.Instance.Authenticated) { throw new ApplicationException("Not authenticated."); } - var entry = Services.SettingsService.Instance.Server.GetDirectoryEntry(); - var filter = string.IsNullOrWhiteSpace(Services.SettingsService.Instance.Server.UserFilter) ? null : - Services.SettingsService.Instance.Server.UserFilter; + var entry = SettingsService.Instance.Server.GetDirectoryEntry(); + var filter = string.IsNullOrWhiteSpace(SettingsService.Instance.Server.UserFilter) ? null : + SettingsService.Instance.Server.UserFilter; var searcher = new DirectorySearcher(entry, filter); var result = searcher.FindAll(); @@ -123,19 +143,19 @@ namespace Bit.Core.Utilities } // Email - if(Services.SettingsService.Instance.Server.EmailPrefixSuffix && - item.Properties.Contains(Services.SettingsService.Instance.Server.UserEmailPrefixAttribute) && - item.Properties[Services.SettingsService.Instance.Server.UserEmailPrefixAttribute].Count > 0 && - !string.IsNullOrWhiteSpace(Services.SettingsService.Instance.Server.UserEmailSuffix)) + if(SettingsService.Instance.Server.EmailPrefixSuffix && + item.Properties.Contains(SettingsService.Instance.Server.UserEmailPrefixAttribute) && + item.Properties[SettingsService.Instance.Server.UserEmailPrefixAttribute].Count > 0 && + !string.IsNullOrWhiteSpace(SettingsService.Instance.Server.UserEmailSuffix)) { user.Email = string.Concat( - item.Properties[Services.SettingsService.Instance.Server.UserEmailPrefixAttribute][0].ToString(), - Services.SettingsService.Instance.Server.UserEmailSuffix).ToLowerInvariant(); + item.Properties[SettingsService.Instance.Server.UserEmailPrefixAttribute][0].ToString(), + SettingsService.Instance.Server.UserEmailSuffix).ToLowerInvariant(); } - else if(item.Properties.Contains(Services.SettingsService.Instance.Server.UserEmailAttribute) && - item.Properties[Services.SettingsService.Instance.Server.UserEmailAttribute].Count > 0) + else if(item.Properties.Contains(SettingsService.Instance.Server.UserEmailAttribute) && + item.Properties[SettingsService.Instance.Server.UserEmailAttribute].Count > 0) { - user.Email = item.Properties[Services.SettingsService.Instance.Server.UserEmailAttribute][0] + user.Email = item.Properties[SettingsService.Instance.Server.UserEmailAttribute][0] .ToString() .ToLowerInvariant(); } @@ -145,8 +165,8 @@ namespace Bit.Core.Utilities } // Dates - user.CreationDate = ParseDate(item.Properties, Services.SettingsService.Instance.Server.CreationDateAttribute); - user.RevisionDate = ParseDate(item.Properties, Services.SettingsService.Instance.Server.RevisionDateAttribute); + user.CreationDate = ParseDate(item.Properties, SettingsService.Instance.Server.CreationDateAttribute); + user.RevisionDate = ParseDate(item.Properties, SettingsService.Instance.Server.RevisionDateAttribute); users.Add(user); } @@ -154,24 +174,7 @@ namespace Bit.Core.Utilities return Task.FromResult(users); } - public static async Task SyncAllAsync() - { - List groups = null; - if(Services.SettingsService.Instance.Server.SyncGroups) - { - groups = await SyncGroupsAsync(); - } - - List users = null; - if(Services.SettingsService.Instance.Server.SyncUsers) - { - users = await SyncUsersAsync(); - } - - FlattenGroupsToUsers(groups, null, groups, users); - } - - private static void FlattenGroupsToUsers(List currentGroups, List currentGroupsUsers, + private static void FlattenGroupsToUsers(List currentGroups, List currentGroupsUsers, List allGroups, List allUsers) { foreach(var group in currentGroups)