1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-10 13:23:18 +00:00

service sync timer. control service from console

This commit is contained in:
Kyle Spearrin
2017-05-16 12:43:07 -04:00
parent de0acb46ea
commit 10a98e4a12
4 changed files with 200 additions and 4 deletions

View File

@@ -1,4 +1,5 @@
using Bit.Core.Models; using Bit.Core.Models;
using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -55,7 +56,7 @@ namespace Bit.Console
Con.WriteLine("4. Configure sync"); Con.WriteLine("4. Configure sync");
Con.WriteLine("5. Simulate directory sync"); Con.WriteLine("5. Simulate directory sync");
Con.WriteLine("6. Sync directory"); Con.WriteLine("6. Sync directory");
Con.WriteLine("7. Start/stop background service"); Con.WriteLine("7. Control background service");
Con.WriteLine("8. Exit"); Con.WriteLine("8. Exit");
Con.WriteLine(); Con.WriteLine();
Con.Write("What would you like to do? "); Con.Write("What would you like to do? ");
@@ -95,9 +96,10 @@ namespace Bit.Console
case "sync": case "sync":
await SyncAsync(); await SyncAsync();
break; break;
case "7":
case "svc": case "svc":
case "service": case "service":
await ServiceAsync();
break; break;
case "exit": case "exit":
case "quit": case "quit":
@@ -697,6 +699,80 @@ namespace Bit.Console
} }
} }
private static Task ServiceAsync()
{
try
{
Con.WriteLine("Service current status: {0}", ControllerService.Instance.StatusString);
}
catch
{
Con.WriteLine("Service unavailable.");
return Task.FromResult(0);
}
var start = false;
var stop = false;
var status = false;
if(_usingArgs)
{
var parameters = ParseParameters();
if(parameters.ContainsKey("start"))
{
start = true;
}
else if(parameters.ContainsKey("stop"))
{
stop = true;
}
}
else
{
Con.WriteLine("1. Start service");
Con.WriteLine("2. Stop service");
Con.WriteLine("3. Check service status");
Con.WriteLine("4. Nothing, go back");
Con.WriteLine();
Con.Write("Option: ");
var selection = Con.ReadLine();
switch(selection)
{
case "1":
case "start":
start = true;
break;
case "2":
case "stop":
stop = true;
break;
case "3":
case "status":
status = true;
break;
default:
break;
}
}
if(start)
{
Con.WriteLine("Starting service...");
ControllerService.Instance.Start();
}
else if(stop)
{
Con.WriteLine("Stopping service...");
ControllerService.Instance.Stop();
}
else if(status)
{
Con.WriteLine("Status: {0}", ControllerService.Instance.StatusString);
}
return Task.FromResult(0);
}
private static string ReadSecureLine() private static string ReadSecureLine()
{ {
var input = string.Empty; var input = string.Empty;

View File

@@ -53,6 +53,7 @@
<Reference Include="System.DirectoryServices" /> <Reference Include="System.DirectoryServices" />
<Reference Include="System.DirectoryServices.Protocols" /> <Reference Include="System.DirectoryServices.Protocols" />
<Reference Include="System.Security" /> <Reference Include="System.Security" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@@ -83,6 +84,7 @@
<Compile Include="Models\ProfileResponse.cs" /> <Compile Include="Models\ProfileResponse.cs" />
<Compile Include="Models\TokenResponse.cs" /> <Compile Include="Models\TokenResponse.cs" />
<Compile Include="Services\ApiService.cs" /> <Compile Include="Services\ApiService.cs" />
<Compile Include="Services\ControllerService.cs" />
<Compile Include="Services\AzureDirectoryService.cs" /> <Compile Include="Services\AzureDirectoryService.cs" />
<Compile Include="Services\LdapDirectoryService.cs" /> <Compile Include="Services\LdapDirectoryService.cs" />
<Compile Include="Services\IDirectoryService.cs" /> <Compile Include="Services\IDirectoryService.cs" />

View File

@@ -0,0 +1,70 @@
using Bit.Core.Enums;
using Bit.Core.Models;
using Bit.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace Bit.Core.Services
{
public class ControllerService
{
private static ControllerService _instance;
private ControllerService()
{
Controller = new ServiceController("bitwarden Directory Connector");
}
public static ControllerService Instance
{
get
{
if(_instance == null)
{
_instance = new ControllerService();
}
return _instance;
}
}
public ServiceController Controller { get; private set; }
public ServiceControllerStatus Status => Controller.Status;
public string StatusString => Controller == null ? "Unavailable" : Status.ToString();
public bool Running => Status == ServiceControllerStatus.Running;
public bool Paused => Status == ServiceControllerStatus.Paused;
public bool Stopped => Status == ServiceControllerStatus.Stopped;
public bool Pending =>
Status == ServiceControllerStatus.ContinuePending ||
Status == ServiceControllerStatus.PausePending ||
Status == ServiceControllerStatus.StartPending ||
Status == ServiceControllerStatus.StopPending;
public bool Start()
{
if(Controller == null || !Stopped)
{
return false;
}
Controller.Start();
return true;
}
public bool Stop()
{
if(Controller == null || !Controller.CanStop)
{
return false;
}
Controller.Stop();
return true;
}
}
}

View File

@@ -1,4 +1,6 @@
using System; using Bit.Core.Services;
using Bit.Core.Utilities;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Data; using System.Data;
@@ -6,7 +8,7 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.ServiceProcess; using System.ServiceProcess;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading;
namespace Service namespace Service
{ {
@@ -15,6 +17,7 @@ namespace Service
{ {
private IContainer _components; private IContainer _components;
private EventLog _eventLog; private EventLog _eventLog;
private Timer _timer;
public Service() public Service()
{ {
@@ -44,6 +47,9 @@ namespace Service
_components?.Dispose(); _components?.Dispose();
_components = null; _components = null;
_timer?.Dispose();
_timer = null;
} }
base.Dispose(disposing); base.Dispose(disposing);
@@ -52,11 +58,53 @@ namespace Service
protected override void OnStart(string[] args) protected override void OnStart(string[] args)
{ {
_eventLog.WriteEntry("Service started!", EventLogEntryType.Information); _eventLog.WriteEntry("Service started!", EventLogEntryType.Information);
if(SettingsService.Instance.Server == null)
{
_eventLog.WriteEntry("Server not configured.", EventLogEntryType.Error);
return;
}
if(SettingsService.Instance.Sync == null)
{
_eventLog.WriteEntry("Sync not configured.", EventLogEntryType.Error);
return;
}
if(!AuthService.Instance.Authenticated || !AuthService.Instance.OrganizationSet)
{
_eventLog.WriteEntry("Not authenticated with proper organization set.", EventLogEntryType.Error);
return;
}
var timerDelegate = new TimerCallback(Callback);
_timer = new Timer(timerDelegate, null, 1000, 60 * 1000);
} }
protected override void OnStop() protected override void OnStop()
{ {
_eventLog.WriteEntry("Service stopped!", EventLogEntryType.Information); _eventLog.WriteEntry("Service stopped!", EventLogEntryType.Information);
} }
private void Callback(object stateInfo)
{
try
{
var result = Sync.SyncAllAsync(false, true).GetAwaiter().GetResult();
if(result.Success)
{
_eventLog.WriteEntry($"Synced {result.Groups.Count} groups, {result.Users.Count} users.",
EventLogEntryType.SuccessAudit);
}
else
{
_eventLog.WriteEntry($"Sync failed: {result.ErrorMessage}", EventLogEntryType.FailureAudit);
}
}
catch(ApplicationException e)
{
_eventLog.WriteEntry($"Sync exception: {e.Message}", EventLogEntryType.Error);
}
}
} }
} }