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:
@@ -1,4 +1,5 @@
|
||||
using Bit.Core.Models;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -55,7 +56,7 @@ namespace Bit.Console
|
||||
Con.WriteLine("4. Configure sync");
|
||||
Con.WriteLine("5. Simulate directory sync");
|
||||
Con.WriteLine("6. Sync directory");
|
||||
Con.WriteLine("7. Start/stop background service");
|
||||
Con.WriteLine("7. Control background service");
|
||||
Con.WriteLine("8. Exit");
|
||||
Con.WriteLine();
|
||||
Con.Write("What would you like to do? ");
|
||||
@@ -95,9 +96,10 @@ namespace Bit.Console
|
||||
case "sync":
|
||||
await SyncAsync();
|
||||
break;
|
||||
case "7":
|
||||
case "svc":
|
||||
case "service":
|
||||
|
||||
await ServiceAsync();
|
||||
break;
|
||||
case "exit":
|
||||
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()
|
||||
{
|
||||
var input = string.Empty;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.DirectoryServices.Protocols" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
@@ -83,6 +84,7 @@
|
||||
<Compile Include="Models\ProfileResponse.cs" />
|
||||
<Compile Include="Models\TokenResponse.cs" />
|
||||
<Compile Include="Services\ApiService.cs" />
|
||||
<Compile Include="Services\ControllerService.cs" />
|
||||
<Compile Include="Services\AzureDirectoryService.cs" />
|
||||
<Compile Include="Services\LdapDirectoryService.cs" />
|
||||
<Compile Include="Services\IDirectoryService.cs" />
|
||||
|
||||
70
src/Core/Services/ControllerService.cs
Normal file
70
src/Core/Services/ControllerService.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
@@ -6,7 +8,7 @@ using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
namespace Service
|
||||
{
|
||||
@@ -15,6 +17,7 @@ namespace Service
|
||||
{
|
||||
private IContainer _components;
|
||||
private EventLog _eventLog;
|
||||
private Timer _timer;
|
||||
|
||||
public Service()
|
||||
{
|
||||
@@ -44,6 +47,9 @@ namespace Service
|
||||
|
||||
_components?.Dispose();
|
||||
_components = null;
|
||||
|
||||
_timer?.Dispose();
|
||||
_timer = null;
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
@@ -52,11 +58,53 @@ namespace Service
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
_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()
|
||||
{
|
||||
_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user