lots of work on cli UI

This commit is contained in:
Kevin Froman 2020-05-23 04:51:17 -05:00
parent b5f8278903
commit 4bb9717891
12 changed files with 301 additions and 11 deletions

View File

@ -7,6 +7,7 @@
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="ConsolePasswordMasker" Version="1.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,27 @@
using treasurechest;
namespace treasurechestCLI {
namespace translations {
internal class Spanish {
internal static void load(Strings stringInst){
stringInst.WELCOME = treasurechest.Version.NAME + " - Protege tu valiosa información";
stringInst.HELP_TEXT = "Ejecuta help para más opciones";
stringInst.EXIT = "Salir de la aplicación";
stringInst.MAIN_MENU_ENCRYPT = "Encriptar";
stringInst.MAIN_MENU_DECRYPT = "Desencriptar";
stringInst.INVALID_OPTION = "Opción inválida";
stringInst.MAIN_MENU_SELECT_INTEGER = "Ingrese un número entero desde el menú";
stringInst.RETURN_TO_PREVIOUS_MENU = "Menú anterior";
stringInst.ENCRYPT_MENU_ENCRYPT_MESSAGE = "Cifrar texto";
stringInst.ENCRYPT_MENU_ENCRYPT_FILE = "Cifrar archivo";
stringInst.ENCRYPT_MENU_USE_PASSPHRASE = "Usar frase de contraseña";
stringInst.ENCRYPT_MENU_USE_PUBKEY = "Usar clave pública";
stringInst.ENTER_MESSAGE_UNTIL_DONE = "Ingrese su mensaje y termine con -q en una nueva línea.";
}
}
}
}

View File

@ -15,30 +15,35 @@ namespace treasurechestCLI {
public string MAIN_MENU_DECRYPT;
public string INVALID_OPTION;
public string MAIN_MENU_SELECT_INTEGER;
public string RETURN_TO_PREVIOUS_MENU;
public string ENCRYPT_MENU_ENCRYPT_MESSAGE;
public string ENCRYPT_MENU_ENCRYPT_FILE;
public string ENCRYPT_MENU_USE_PASSPHRASE;
public string ENCRYPT_MENU_USE_PUBKEY;
public string ENTER_MESSAGE_UNTIL_DONE;
public Strings(){
switch (GetLanguage.language){
case "es":
WELCOME = treasurechest.Version.NAME + " - Protege tu valiosa información";
HELP_TEXT = "Ejecuta help para más opciones";
EXIT = "Salida";
MAIN_MENU_ENCRYPT = "Encriptar";
MAIN_MENU_DECRYPT = "Desencriptar";
INVALID_OPTION = "Opción inválida";
MAIN_MENU_SELECT_INTEGER = "Ingrese un número entero desde el menú";
Spanish.load(this);
break;
case "en":
default:
WELCOME = treasurechest.Version.NAME + " - Protect your treasured information";
HELP_TEXT = "Run with help for more options";
EXIT = "Exit";
EXIT = "Exit application";
MAIN_MENU_ENCRYPT = "Encrypt";
MAIN_MENU_DECRYPT = "Decrypt";
INVALID_OPTION = "Invalid option";
MAIN_MENU_SELECT_INTEGER = "Enter an integer from the menu";
RETURN_TO_PREVIOUS_MENU = "Previous menu";
ENCRYPT_MENU_ENCRYPT_MESSAGE = "Encrypt text";
ENCRYPT_MENU_ENCRYPT_FILE = "Encrypt file";
ENCRYPT_MENU_USE_PASSPHRASE = "Use passphrase";
ENCRYPT_MENU_USE_PUBKEY = "Use public key";
ENTER_MESSAGE_UNTIL_DONE = "Enter your message and finish with -q on a new line.";
break;
}

View File

@ -0,0 +1,55 @@
using System;
using treasurechest.STDIOWrapper;
namespace treasurechestCLI{
internal class EncryptMessageInterface{
public static void EncryptMessage(){
int choice = 0;
int counter = 1;
translations.Strings strings = new translations.Strings();
string[] encryptMenuOptions =
{
strings.ENCRYPT_MENU_USE_PASSPHRASE,
strings.ENCRYPT_MENU_USE_PUBKEY,
strings.RETURN_TO_PREVIOUS_MENU
};
while(true){
foreach(string option in encryptMenuOptions){
STDIO.O(counter.ToString() + ". " + option);
counter += 1;
}
try{
choice = Int32.Parse(System.Console.ReadLine());
}
catch (System.OverflowException){
// User being silly with input
STDIO.O(strings.MAIN_MENU_SELECT_INTEGER);
counter = 1;
}
catch(System.FormatException){
// Too lazy to check strings, force them to use int from menu which is faster anyway
STDIO.O(strings.MAIN_MENU_SELECT_INTEGER);
counter = 1;
}
catch(System.ArgumentNullException){
// Can happen when stream closes (e.g. ctrl-d)
// since menu is intended to be directly human interfaced, user probably wants to exit
choice = encryptMenuOptions.Length;
}
if (choice == 1){
GetMessage.getTypedMessage();
}
else if (choice == encryptMenuOptions.Length){
break;
}
counter = 1;
}
}
}
}

View File

@ -0,0 +1,28 @@
using treasurechest.STDIOWrapper;
using System;
namespace treasurechestCLI{
internal class GetMessage{
internal static string getTypedMessage(){
translations.Strings strings = new translations.Strings();
string message = "";
string line = "";
STDIO.O(strings.ENTER_MESSAGE_UNTIL_DONE);
while (true){
line = Console.ReadLine();
if (line.Equals("-q")){
break;
}
message += line;
}
return message;
}
}
}

View File

@ -0,0 +1,61 @@
using System;
using treasurechest.STDIOWrapper;
using treasurechest;
namespace treasurechestCLI
{
internal class EncryptMenu{
public static void enterMenu(translations.Strings strings) {
int choice = 0;
int counter = 1;
string[] encryptMenuOptions =
{
strings.ENCRYPT_MENU_ENCRYPT_MESSAGE,
strings.ENCRYPT_MENU_ENCRYPT_FILE,
strings.RETURN_TO_PREVIOUS_MENU,
strings.EXIT
};
while (true){
foreach (string option in encryptMenuOptions){
STDIO.O(counter.ToString() + ". " + option);
counter += 1;
}
try{
choice = Int32.Parse(System.Console.ReadLine());
}
catch (System.OverflowException){
// User being silly with input
STDIO.O(strings.MAIN_MENU_SELECT_INTEGER);
counter = 1;
}
catch(System.FormatException){
// Too lazy to check strings, force them to use int from menu which is faster anyway
STDIO.O(strings.MAIN_MENU_SELECT_INTEGER);
counter = 1;
}
catch(System.ArgumentNullException){
// Can happen when stream closes (e.g. ctrl-d)
// since menu is intended to be directly human interfaced, user probably wants to exit
choice = encryptMenuOptions.Length;
}
if (choice == 1){
EncryptMessageInterface.EncryptMessage();
}
else if (choice == encryptMenuOptions.Length - 1){
return;
}
else if (choice == encryptMenuOptions.Length){
System.Environment.Exit(0);
}
counter = 1;
}
}
}
}

View File

@ -1,5 +1,4 @@
using System;
using CommandLine;
using treasurechest.STDIOWrapper;
using treasurechest;
@ -45,7 +44,11 @@ namespace treasurechestCLI
// since menu is intended to be directly human interfaced, user probably wants to exit
choice = mainMenuOptionsSize;
}
if (choice == mainMenuOptionsSize){
if (choice == 1){
EncryptMenu.enterMenu(strings);
}
else if (choice == mainMenuOptionsSize){
// Exit is final option
break;
}
else{

49
tests/simplepackTest.cs Normal file
View File

@ -0,0 +1,49 @@
using NUnit.Framework;
using chestcrypto;
using System;
namespace simplepackTests
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void TestPackUnpackString()
{
string message = "hello world";
string packed;
packed = chestcrypto.simplepack.SimplePack.pack(message);
Assert.AreEqual(message, chestcrypto.simplepack.SimplePack.unpack(packed));
}
[Test]
public void TestPackUnpackBytes()
{
byte[] message = System.Text.Encoding.UTF8.GetBytes("hello world");
string packed;
packed = chestcrypto.simplepack.SimplePack.pack(message);
Assert.AreEqual(message, chestcrypto.simplepack.SimplePack.unpack(packed));
}
[Test]
public void TestPackUnpackInvalid(){
byte[] message = System.Text.Encoding.UTF8.GetBytes("hello world");
string packed;
packed = chestcrypto.simplepack.SimplePack.pack(message).Remove(1);
bool success = false;
try{
chestcrypto.simplepack.SimplePack.unpack(packed);
}
catch(chestcrypto.exceptions.InvalidSimplePackMessage){
success = true;
}
if (! success){
Assert.Fail();
}
}
}
}

View File

@ -0,0 +1,23 @@
using System;
namespace chestcrypto{
namespace exceptions{
public class InvalidSimplePackMessage : Exception
{
public InvalidSimplePackMessage()
{
}
public InvalidSimplePackMessage(string message)
: base(message)
{
}
public InvalidSimplePackMessage(string message, Exception inner)
: base(message, inner)
{
}
}
}
}

View File

@ -0,0 +1,37 @@
using Base58Check;
using System;
namespace chestcrypto{
namespace simplepack{
public class SimplePack{
private const string header = "CHEST-MESSAGE";
private const string footer = "END-CHEST-MESSAGE.";
public static string pack(byte[] data){
return header + Base58CheckEncoding.Encode(data) + footer;
}
public static string pack(string data){
return pack(System.Text.Encoding.UTF8.GetBytes(data));
}
public static byte[] unpack(string checkedBase58String){
if (! checkedBase58String.Contains(header) | ! checkedBase58String.Contains(footer)){
throw new exceptions.InvalidSimplePackMessage("Message does not have valid header and footer");
}
string encodedMessage = "";
for (int i = header.Length; i < checkedBase58String.Length - footer.Length; i++){
encodedMessage += checkedBase58String[i];
}
return Base58CheckEncoding.Decode(encodedMessage);
}
}
}
}

View File

@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Base58Check" Version="0.2.0" />
<PackageReference Include="MessagePack" Version="2.1.115" />
<PackageReference Include="Sodium.Core" Version="1.2.3" />
</ItemGroup>