From 2e196c6f7a227674a4539ef0d8ad23e108c64de8 Mon Sep 17 00:00:00 2001 From: erinn Date: Sat, 21 Mar 2020 12:29:18 -0700 Subject: [PATCH] sigh --- api/api.go | 10 ++- go.mod | 3 +- go.sum | 41 +-------- lockbox.go | 2 +- qml/main.qml | 248 +++++++++++++++++++++++++++------------------------ 5 files changed, 146 insertions(+), 158 deletions(-) diff --git a/api/api.go b/api/api.go index a9d9157..66a7a40 100644 --- a/api/api.go +++ b/api/api.go @@ -14,6 +14,7 @@ import ( "io/ioutil" "os" path "path/filepath" + "sort" "strings" ) @@ -67,8 +68,15 @@ func (lapi *LockBoxAPI) decryptFile(inputFilename string, outputFilename string, if schemeDefined == false { for k := range data { schema = append(schema, k) - outputLine += fmt.Sprintf(`"%v",`, strings.ReplaceAll(k, "\"", "\\\"")) } + + sort.Strings(schema) + + for _, k := range schema { + str := strings.SplitN(k, "_", 1) + outputLine += fmt.Sprintf(`"%v",`, strings.ReplaceAll(str[1], "\"", "\\\"")) + } + outputfile = append(outputfile, outputLine) schemeDefined = true } diff --git a/go.mod b/go.mod index 4a585de..4c05f7a 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,9 @@ module git.openprivacy.ca/openprivacy/lockbox go 1.13 require ( - cwtch.im/tapir v0.1.17 // indirect git.openprivacy.ca/openprivacy/log v1.0.0 github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41 github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41 // indirect github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41 // indirect - golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a + golang.org/x/crypto v0.0.0-20200320181102-891825fb96df ) diff --git a/go.sum b/go.sum index 8f6a641..dd933fc 100644 --- a/go.sum +++ b/go.sum @@ -1,31 +1,11 @@ -cwtch.im/tapir v0.1.17 h1:2jVZUe1a88tMI4aJPvRTO4Id3NN3PsM62cT5lntEChk= -cwtch.im/tapir v0.1.17/go.mod h1:HzezugpEx+nZ3LdyDsl0w6n45IJYnOt8uqldkLWmaqs= -git.openprivacy.ca/openprivacy/connectivity v1.1.0 h1:9PEeKuPdoIRYeA62BUkBW2BfK4KqKEXz1fvUxZoP4xs= -git.openprivacy.ca/openprivacy/connectivity v1.1.0/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= -git.openprivacy.ca/openprivacy/connectivity v1.1.1 h1:hKxBOmxP7Jdu3K1BJ93mRtKNiWUoP6YHt/o2snE2Z0w= -git.openprivacy.ca/openprivacy/connectivity v1.1.1/go.mod h1:4P8mirZZslKbo2zBrXXVjgEdqGwHo/6qoFBwFQW6d6E= -git.openprivacy.ca/openprivacy/libricochet-go v1.0.11 h1:C7QFFzG0p5XKu0zcOIdLGwEpA9uU0BceBM7CfVK5D40= git.openprivacy.ca/openprivacy/log v1.0.0 h1:Rvqm1weUdR4AOnJ79b1upHCc9vC/QF1rhSD2Um7sr1Y= git.openprivacy.ca/openprivacy/log v1.0.0/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= -github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI= -github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0= -github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca h1:Q2r7AxHdJwWfLtBZwvW621M3sPqxPc6ITv2j1FGsYpw= -github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtwjRGkAuDEJeWNOv3a2hUouSP/yRYXmvHw= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e h1:XWcjeEtTFTOVA9Fs1w7n2XBftk5ib4oZrhzWk0B+3eA= github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= -github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= -github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -34,40 +14,25 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/therecipe/qt v0.0.0-20191101232336-18864661ae4f h1:06ICDSmDOBUC9jwgv44ngvyHzwudJNLa5H+rbCyDFRY= -github.com/therecipe/qt v0.0.0-20191101232336-18864661ae4f/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us= github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41 h1:yBVcrpbaQYJBdKT2pxTdlL4hBE/eM4UPcyj9YpyvSok= github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us= -github.com/therecipe/qt/internal/binding/files/docs v0.0.0-20191019224306-1097424d656c h1:/VhcwU7WuFEVgDHZ9V8PIYAyYqQ6KNxFUjBMOf2aFZM= github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41 h1:My9HYsfDI/fJPZGyilw6066buBiZ7pgKRRgAyvKK5lA= github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:7m8PDYDEtEVqfjoUQc2UrFqhG0CDmoVJjRlQxexndFc= -github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20191101232336-18864661ae4f h1:NLmalUtBOLr8mUB1/um4PO1KAx66AXlQF/lkrg5vTek= -github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20191101232336-18864661ae4f/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4= github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41 h1:jTzKrQ6EIPvKw1B9/wwoKJLrXF+ManMsXoUzufxAdsg= github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a h1:aczoJ0HPNE92XKa7DrIzkNN6esOKO2TBwiiYoKcINhA= -golang.org/x/crypto v0.0.0-20200206161412-a0c6ece9d31a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200320181102-891825fb96df h1:lDWgvUvNnaTnNBc/dwOty86cFeKoKWbwy2wQj0gIxbU= +golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a h1:XCr/YX7O0uxRkLq2k1ApNQMims9eCioF9UpzIPBDmuo= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190420181800-aa740d480789 h1:FF0rjo15h51+N6642mf5S3QuplmKo2aCrJUYkHTx85s= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/lockbox.go b/lockbox.go index ff7f373..301382a 100644 --- a/lockbox.go +++ b/lockbox.go @@ -17,7 +17,7 @@ func main() { app := widgets.NewQApplication(len(os.Args), os.Args) app.SetAttribute(core.Qt__AA_EnableHighDpiScaling, true) - quickcontrols2.QQuickStyle_SetStyle("Material") + quickcontrols2.QQuickStyle_SetStyle("Default") engine := qml.NewQQmlApplicationEngine(nil) lockapi := api.NewLockBoxAPI(nil) diff --git a/qml/main.qml b/qml/main.qml index f50b032..41734e1 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -4,8 +4,7 @@ import QtQuick.Controls 2.12 import QtQuick 2.12 import QtQuick.Dialogs 1.3 import QtQuick.Layouts 1.12 - - +import QtQuick.Controls 1.4 ApplicationWindow { id: root @@ -14,11 +13,6 @@ ApplicationWindow { minimumWidth: 640 minimumHeight: 640 - background: Rectangle { - visible: true - color: "#FDF3FC" - } - FileDialog { id: fileDialog title: "Please choose a file to decrypt" @@ -36,121 +30,143 @@ ApplicationWindow { Component.onCompleted: visible = false } - Column { - anchors.horizontalCenter: parent.horizontalCenter - width:parent.width - padding:10 + TabView { + anchors.fill: parent - Row { - width:parent.width - padding:10 - Label { - text: "Decrypt a File" - font.pixelSize: 22 - } - } + Tab { + title: "Instructions" - Row { - width:parent.width - padding:10 - TextField { - width:parent.width * 0.50 - id:inputFileLabel - placeholderText: "Select an Input File" - } - Button { - Layout.alignment: Qt.AlignRight - text: "Select File To Decrypt" - onClicked: fileDialog.visible = true - } - } - Row { - width:parent.width - padding:10 - TextField { - id:outputFileLabel - width:parent.width * 0.50 - placeholderText: "Select an Output File" - } - Button { - Layout.alignment: Qt.AlignRight - text: "Select File To Output" - onClicked: outputFileDialog.visible = true - } - } - Row { - width:parent.width - padding:10 - TextField { - width:parent.width * 0.50 - id:keyFileLabel - placeholderText: "Select a Key File" - } - Button { - Layout.alignment: Qt.AlignRight - text: "Select Private Key" - onClicked: keyFileDialog.visible = true - } - } - Row { - width:parent.width - padding:10 - Button { - text: "Decrypt" - onClicked: function() { - lockbox.decryptFile(fileDialog.fileUrls[0],outputFileDialog.fileUrls[0],keyFileDialog.fileUrls[0]) - } - } - } - Row { - width:parent.width - padding:10 - Rectangle { - width: parent.width * 0.9 - height: 1 - color: "#dcb8d5" - border.color: "#dcb8d5" - border.width: 1 - } - } + Column { + anchors.fill: parent + padding: 10 - Row { - width:parent.width - padding:10 - Label { - text: "Generate New Encryption Keys" - font.pixelSize: 22 - } - } - Row { - width:parent.width - padding:10 - TextField { - width:parent.width * 0.50 - id:keyFileGenLabel - placeholderText: "Select a Key File" - } - Button { - Layout.alignment: Qt.AlignRight - text: "Select a Folder to Save Keys" - onClicked: function() { - keyFileCreateDialog.visible = true - } - } - } + Label { + width: parent.width + wrapMode: Text.WordWrap + rightPadding: 10 + text: "This application works in two steps:\n\n1. Use the Generate Keys tab to create files named 'key.public' and 'key.private'. These are encryption and decryption keys, respectively. The public key should be sent to whoever set up the partner web app. The private key should be backed up to a USB stick or somewhere else trustworthy for backup, but you should be careful not to send it over the internet!\n\n2. Once you have downloaded the submissions.dat file from the web app's admin panel, use the Decrypt tab and the private key file from earlier to decrypt the file. It will output a CSV (spreadsheet) file that can be opened in office programs." + } + } + } - Row { - width:parent.width - Button { - text: "Generate a Decryption Key" - onClicked: function() { - lockbox.generateKey(keyFileCreateDialog.fileUrls[0]) - } - } - } + Tab { + title: "Generate Keys" - } + Column { + padding: 10 + width: parent.width + Row { + width:parent.width + padding:10 + Label { + text: "Generate New Encryption Keys" + font.pixelSize: 22 + } + } + Row { + width:parent.width + padding:10 + TextField { + width:parent.width * 0.50 + id:keyFileGenLabel + placeholderText: "Folder to save keys into" + } + Button { + Layout.alignment: Qt.AlignRight + text: "Browse..." + onClicked: function() { + keyFileCreateDialog.visible = true + } + } + } + + Row { + width:parent.width + padding: 10 + Button { + text: "Generate!" + onClicked: function() { + lockbox.generateKey(keyFileCreateDialog.fileUrls[0]) + } + } + } + + } + } + + Tab { + title: "Decrypt" + + Column { + anchors.fill: parent + padding:10 + + Row { + width:parent.width + padding:10 + + Label { + text: "Decrypt submissions" + font.pixelSize: 22 + } + } + + Row { + width:parent.width + padding:10 + TextField { + width:parent.width * 0.75 + id:inputFileLabel + placeholderText: "Encrypted submissions file (.dat)" + } + Button { + Layout.alignment: Qt.AlignRight + text: "Browse..." + onClicked: fileDialog.visible = true + } + } + Row { + width:parent.width + padding:10 + TextField { + id:outputFileLabel + width:parent.width * 0.75 + placeholderText: "Location for decrypted file (.csv)" + } + Button { + Layout.alignment: Qt.AlignRight + text: "Browse..." + onClicked: outputFileDialog.visible = true + } + } + Row { + width:parent.width + padding:10 + TextField { + width:parent.width * 0.75 + id:keyFileLabel + placeholderText: "Decryption key file (.private)" + } + Button { + Layout.alignment: Qt.AlignRight + text: "Browse..." + onClicked: keyFileDialog.visible = true + } + } + Row { + width:parent.width + padding:10 + Button { + text: "Decrypt!" + onClicked: function() { + lockbox.decryptFile(fileDialog.fileUrls[0],outputFileDialog.fileUrls[0],keyFileDialog.fileUrls[0]) + } + } + } + } + } + } FileDialog { id: outputFileDialog