1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-10 13:23:18 +00:00
Files
directory-connector/src/Console/Program.cs
2017-05-13 16:20:00 -04:00

432 lines
14 KiB
C#

using Bit.Core.Models;
using Bit.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Con = System.Console;
namespace Bit.Console
{
class Program
{
private static bool _usingArgs = false;
private static bool _exit = false;
private static string[] _args = null;
static void Main(string[] args)
{
MainAsync(args).Wait();
}
private static async Task MainAsync(string[] args)
{
_args = args;
_usingArgs = args.Length > 0;
string selection = null;
while(true)
{
Con.ResetColor();
if(_usingArgs)
{
selection = args[0];
}
else
{
Con.WriteLine("Main Menu");
Con.WriteLine("=================================");
Con.WriteLine("1. Log in to bitwarden");
Con.WriteLine("2. Log out");
Con.WriteLine("3. Configure directory connection");
Con.WriteLine("4. Sync directory");
Con.WriteLine("5. Start/stop background service");
Con.WriteLine("6. Exit");
Con.WriteLine();
Con.Write("What would you like to do? ");
selection = Con.ReadLine();
Con.WriteLine();
}
switch(selection)
{
case "1":
case "login":
case "signin":
await LogInAsync();
break;
case "2":
case "logout":
case "signout":
await LogOutAsync();
break;
case "3":
case "dir":
case "directory":
await DirectoryAsync();
break;
case "4":
case "sync":
await SyncAsync();
break;
case "svc":
case "service":
break;
case "exit":
case "quit":
case "q":
_exit = true;
break;
default:
Con.WriteLine("Unknown command.");
break;
}
if(_exit || _usingArgs)
{
break;
}
else
{
Con.WriteLine();
Con.WriteLine();
}
}
_args = null;
}
private static async Task LogInAsync()
{
if(Core.Services.AuthService.Instance.Authenticated)
{
Con.WriteLine("You are already logged in as {0}.", Core.Services.TokenService.Instance.AccessTokenEmail);
return;
}
string email = null;
string masterPassword = null;
string token = null;
string orgId = null;
if(_usingArgs)
{
var parameters = ParseParameters();
if(parameters.Count >= 2 && parameters.ContainsKey("e") && parameters.ContainsKey("p"))
{
email = parameters["e"];
masterPassword = parameters["p"];
}
if(parameters.Count >= 3 && parameters.ContainsKey("t"))
{
token = parameters["t"];
}
if(parameters.Count >= 3 && parameters.ContainsKey("o"))
{
orgId = parameters["o"];
}
}
else
{
Con.Write("Email: ");
email = Con.ReadLine().Trim();
Con.Write("Master password: ");
masterPassword = ReadSecureLine();
}
if(string.IsNullOrWhiteSpace(email) || string.IsNullOrWhiteSpace(masterPassword))
{
Con.WriteLine();
Con.WriteLine();
Con.ForegroundColor = ConsoleColor.Red;
Con.WriteLine("Invalid input parameters.");
Con.ResetColor();
return;
}
LoginResult result = null;
if(string.IsNullOrWhiteSpace(token))
{
result = await Core.Services.AuthService.Instance.LogInAsync(email, masterPassword);
}
else
{
result = await Core.Services.AuthService.Instance.LogInTwoFactorAsync(email, masterPassword, token);
}
if(string.IsNullOrWhiteSpace(token) && result.TwoFactorRequired)
{
Con.WriteLine();
Con.WriteLine();
Con.WriteLine("Two-step login is enabled on this account. Please enter your verification code.");
Con.Write("Verification code: ");
token = Con.ReadLine().Trim();
result = await Core.Services.AuthService.Instance.LogInTwoFactorWithHashAsync(token, email,
result.MasterPasswordHash);
}
if(result.Success && result.Organizations.Count > 1)
{
Organization org = null;
if(string.IsNullOrWhiteSpace(orgId))
{
org = result.Organizations.FirstOrDefault(o => o.Id == orgId);
}
else
{
Con.WriteLine();
Con.WriteLine();
for(int i = 0; i < result.Organizations.Count; i++)
{
Con.WriteLine("{0}. {1}", i + 1, result.Organizations[i].Name);
}
Con.Write("Select your organization: ");
var orgIndexInput = Con.ReadLine().Trim();
int orgIndex;
if(int.TryParse(orgIndexInput, out orgIndex))
{
org = result.Organizations[orgIndex];
}
}
if(org == null)
{
result.Success = false;
result.ErrorMessage = "Organization not found.";
Core.Services.AuthService.Instance.LogOut();
}
else
{
Core.Services.SettingsService.Instance.Organization = org;
}
}
Con.WriteLine();
Con.WriteLine();
if(result.Success)
{
Con.ForegroundColor = ConsoleColor.Green;
Con.WriteLine("You have successfully logged in as {0}!", Core.Services.TokenService.Instance.AccessTokenEmail);
Con.ResetColor();
}
else
{
Con.ForegroundColor = ConsoleColor.Red;
Con.WriteLine(result.ErrorMessage);
Con.ResetColor();
}
masterPassword = null;
}
private static Task LogOutAsync()
{
if(Core.Services.AuthService.Instance.Authenticated)
{
Core.Services.AuthService.Instance.LogOut();
Con.ForegroundColor = ConsoleColor.Green;
Con.WriteLine("You have successfully logged out!");
Con.ResetColor();
}
else
{
Con.WriteLine("You are not logged in.");
}
return Task.FromResult(0);
}
private static Task DirectoryAsync()
{
var config = new ServerConfiguration();
if(_usingArgs)
{
var parameters = ParseParameters();
if(parameters.ContainsKey("a"))
{
config.Address = parameters["a"];
}
if(parameters.ContainsKey("port"))
{
config.Port = parameters["port"];
}
if(parameters.ContainsKey("path"))
{
config.Path = parameters["path"];
}
if(parameters.ContainsKey("u"))
{
config.Username = parameters["u"];
}
if(parameters.ContainsKey("p"))
{
config.Password = new EncryptedData(parameters["p"]);
}
if(parameters.ContainsKey("gf"))
{
config.GroupFilter = parameters["gf"];
}
if(parameters.ContainsKey("uf"))
{
config.UserFilter = parameters["uf"];
}
}
else
{
string input;
Con.Write("Address: ");
config.Address = Con.ReadLine().Trim();
Con.Write("Port [{0}]: ", config.Port);
input = Con.ReadLine().Trim();
if(!string.IsNullOrWhiteSpace(input))
{
config.Port = input;
}
Con.Write("Path: ");
config.Path = Con.ReadLine().Trim();
Con.Write("Username: ");
config.Username = Con.ReadLine().Trim();
Con.Write("Password: ");
input = ReadSecureLine();
if(!string.IsNullOrWhiteSpace(input))
{
config.Password = new EncryptedData(input);
input = null;
}
Con.WriteLine();
Con.Write("Sync groups? [y]: ");
input = Con.ReadLine().Trim().ToLower();
config.SyncGroups = input == "y" || input == "yes" || string.IsNullOrWhiteSpace(input);
if(config.SyncGroups)
{
Con.Write("Group filter [{0}]: ", config.GroupFilter);
input = Con.ReadLine().Trim();
if(!string.IsNullOrWhiteSpace(input))
{
config.GroupFilter = input;
}
Con.Write("Group name attribute [{0}]: ", config.GroupNameAttribute);
input = Con.ReadLine().Trim();
if(!string.IsNullOrWhiteSpace(input))
{
config.GroupNameAttribute = input;
}
}
Con.Write("Sync users? [y]: ");
input = Con.ReadLine().Trim().ToLower();
config.SyncUsers = input == "y" || input == "yes" || string.IsNullOrWhiteSpace(input);
if(config.SyncUsers)
{
Con.Write("User filter [{0}]: ", config.UserFilter);
input = Con.ReadLine().Trim();
if(!string.IsNullOrWhiteSpace(input))
{
config.UserFilter = input;
}
Con.Write("User email attribute [{0}]: ", config.UserEmailAttribute);
input = Con.ReadLine().Trim();
if(!string.IsNullOrWhiteSpace(input))
{
config.GroupNameAttribute = input;
}
}
input = null;
}
Con.WriteLine();
Con.WriteLine();
if(string.IsNullOrWhiteSpace(config.Address))
{
Con.ForegroundColor = ConsoleColor.Red;
Con.WriteLine("Invalid input parameters.");
Con.ResetColor();
}
else
{
Core.Services.SettingsService.Instance.Server = config;
Con.ForegroundColor = ConsoleColor.Green;
Con.WriteLine("Saved directory server configuration.");
Con.ResetColor();
}
return Task.FromResult(0);
}
private static async Task SyncAsync()
{
if(!Core.Services.AuthService.Instance.Authenticated)
{
Con.WriteLine("You are not logged in.");
}
else if(Core.Services.SettingsService.Instance.Server == null)
{
Con.WriteLine("Server is not configured.");
}
else
{
Con.WriteLine("Syncing...");
await Sync.SyncAllAsync();
Con.ForegroundColor = ConsoleColor.Green;
Con.WriteLine("Syncing complete.");
Con.ResetColor();
}
}
private static string ReadSecureLine()
{
var input = string.Empty;
while(true)
{
var i = Con.ReadKey(true);
if(i.Key == ConsoleKey.Enter)
{
break;
}
else if(i.Key == ConsoleKey.Backspace)
{
if(input.Length > 0)
{
input = input.Remove(input.Length - 1);
Con.Write("\b \b");
}
}
else
{
input = string.Concat(input, i.KeyChar);
Con.Write("*");
}
}
return input;
}
private static IDictionary<string, string> ParseParameters()
{
var dict = new Dictionary<string, string>();
for(int i = 1; i < _args.Length; i = i + 2)
{
if(!_args[i].StartsWith("-"))
{
continue;
}
dict.Add(_args[i].Substring(1), _args[i + 1]);
}
return dict;
}
}
}