From 581c395a17bf711a1036b7efb18a5e0ba7560c22 Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Thu, 29 Jan 2026 16:09:17 +0100 Subject: [PATCH] feat: rewrite parts for readability --- src/draw.go | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.go | 263 ++++------------------------------------------ 2 files changed, 310 insertions(+), 245 deletions(-) create mode 100644 src/draw.go diff --git a/src/draw.go b/src/draw.go new file mode 100644 index 0000000..678db68 --- /dev/null +++ b/src/draw.go @@ -0,0 +1,292 @@ +package main + +import ( + "log" + "os" + "path/filepath" + certpair "runesmith/src/modules/certpairs" + "slices" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/dialog" + "fyne.io/fyne/v2/layout" + "fyne.io/fyne/v2/storage" + "fyne.io/fyne/v2/widget" +) + +func drawSelecRow(keyPath, certPath, choice *string, caRadio *widget.RadioGroup, w *fyne.Window) *fyne.Container { + // Issuer entry + issuerText := widget.NewLabel("Certificate issuer will appear here...") + issuerText.Selectable = true + + // Labels to show selected filenames + keyLabel := widget.NewLabel("No file selected") + certLabel := widget.NewLabel("No file selected") + + // Certificate file + certBtn := widget.NewButton("Upload Certificate File", func() { + // Use NewFileOpen to get the dialog object + certDiag := dialog.NewFileOpen(func(r fyne.URIReadCloser, err error) { + defer r.Close() + + if r != nil { + certLabel.SetText(r.URI().Name()) + *certPath = r.URI().Path() + + certData := readFile(*certPath) + certObj := parseX509(certData) + *choice = certObj.Issuer.CommonName + log.Println("Issuer:", *choice) + issuerText.SetText(*choice) + + if slices.Contains(caChoices, *choice) { + caRadio.SetSelected(*choice) + } + } + }, *w) + certFilter := storage.NewExtensionFileFilter(crtTextFilter) + certDiag.SetFilter(certFilter) + + // Resize the dialog + certDiag.Resize(windowSize) + certDiag.Show() + }) + + certBtnWrap := container.NewGridWrap( + buttonSize, + certBtn, + ) + + // Certificate Keyfile + keyBtn := widget.NewButton("Upload Private Key File", func() { + keyDiag := dialog.NewFileOpen(func(r fyne.URIReadCloser, err error) { + defer r.Close() + + if r != nil { + keyLabel.SetText(r.URI().Name()) + *keyPath = r.URI().Path() + } + }, *w) + keyFilter := storage.NewExtensionFileFilter(keyTextFilter) + keyDiag.SetFilter(keyFilter) + + keyDiag.Resize(windowSize) + keyDiag.Show() + }) + + keyBtnWrap := container.NewGridWrap( + buttonSize, + keyBtn, + ) + + certRow := container.NewHBox(certBtnWrap, certLabel) + keyRow := container.NewHBox(keyBtnWrap, keyLabel) + + wholeSelecRow := container.NewVBox( + certRow, + keyRow, + widget.NewLabel(""), + issuerText, + ) + + return wholeSelecRow +} + +func drawChainRow(choice *string) (*fyne.Container, *widget.RadioGroup) { + infoLabel := widget.NewLabel("If needed you can override the selection.\nOtherwise let the application decide.") + + caRadio := widget.NewRadioGroup(caChoices, func(selected string) { + switch selected { + case "Sectigo Public Server Authentication CA DV R36": + log.Println("Sectigo Public Server Authentication CA DV R36") + *choice = "SectigoNew" + case "Sectigo RSA Domain Validation Secure Server CA": + log.Println("Sectigo RSA Domain Validation Secure Server CA") + *choice = "SectigoOld" + default: //Fallback + *choice = "SectigoNew" + } + }) + + chainRow := container.NewHBox( + infoLabel, + caRadio, + ) + + return chainRow, caRadio +} + +func drawPersPassRow(writePassDown *bool, overwritePassDown *bool) *fyne.Container { + // Render the overwrite checkfox first since I need its variable/object to disable/enable in the next checkbox (which is visually above this one) + overwriteCheckBox := widget.NewCheck("Overwrite possible existing 'pkcs_password' file", func(checked bool) { + if checked { + log.Println("Checked box: overwrite if file exists.") + *overwritePassDown = true + } else { + log.Println("Unchecked box: not overwriting if file exists.") + *overwritePassDown = false + } + }) + // Disable the checkbox by default since its reliant on the writeCheckBox + overwriteCheckBox.Disable() + + writeCheckBox := widget.NewCheck("Save password to file", func(checked bool) { + if checked { + log.Println("Checked box: saving to file.") + *writePassDown = true + overwriteCheckBox.Enable() + } else { + log.Println("Unchecked box: not saving to file") + *writePassDown = false + overwriteCheckBox.Disable() + } + }) + + persPassBoxes := container.NewVBox( + writeCheckBox, + overwriteCheckBox, + ) + + return persPassBoxes +} + +func drawStatusRow() (*fyne.Container, *widget.Label) { + // Status label, where pfx pass will appear + statusText := widget.NewLabel("Status will appear here...") + statusText.Selectable = true + + statusRow := container.NewHBox( + statusText, + ) + + return statusRow, statusText +} + +func drawActionRow(keyPath, certPath, choice *string, + writePassDown, overwritePassDown *bool, + statusLabel *widget.Label, + w *fyne.Window, + app fyne.App) *fyne.Container { + + actionBtn := widget.NewButton("Generate", func() { + files := []string{*keyPath, *certPath} + + // The following structure is basic but can easily be expanded to fit more pairs + // 0 = ROOT + // 1 = CA + // As per spec in the certpair module. + var certPair []string + switch *choice { + case "SectigoNew": + certPair = certpair.SectigoNewChain + case "SectigoOld": + certPair = certpair.SectigoOldChain + } + + // Check if one of the filepaths is empty + allPresent := true + if slices.Contains(files, "") { + allPresent = false + } + + // Check if all needed file/data is present + if !allPresent { + statusLabel.SetText("One or more files missing!") + log.Println("One or more files missing!") + return + } + + // Generate the PKCS file with the given data + pfxPass, pfxData := integrityCheckAndGo(*keyPath, *certPath, certPair[1], certPair[0]) + + // Check if the data returned is OK + if len(pfxData) == 0 || pfxData == nil { + log.Println("Something went wrong while creating the PKCS file...") + statusLabel.SetText("Something went wrong while creating the PKCS file...") + } + + // Most important dialog next, saving the PKCS somewhere + // We also need to declare some variables because otherwise theyd become out of scope + var desiredPath string + var defaultName string = "certificate_store.pfx" + + svDialog := dialog.NewFileSave( + func(writer fyne.URIWriteCloser, err error) { + defer writer.Close() + + desiredPath = writer.URI().Path() + desiredParentPath := filepath.Dir(desiredPath) + + if err != nil { + dialog.ShowError(err, *w) + } + if writer == nil { + // User cancelled + } + + _, err = writer.Write(pfxData) + if err != nil { + dialog.ShowError(err, *w) + } + + var dnText string = "PKCS file saved to: " + desiredPath + "\nThe password for the generated pkcs file is:\n\n" + pfxPass + + // Write down the PKCS password on the filesystem + if *writePassDown { + wholePath := desiredParentPath + "/pkcs_password" + var alreadyExists bool + + if _, err := os.Stat(wholePath); err == nil { + alreadyExists = true + } else if os.IsNotExist(err) { + alreadyExists = false + } else { // Failsafe if something unforeseen happens + alreadyExists = true + } + + if alreadyExists && !*overwritePassDown { + log.Println("File already exists and overwrite checkbox is unchecked.") + dnText += "\n\nCAREFUL! PKCS password was NOT written down. File exists! NOT OVERWRITING!" + } else { + log.Println("Writing PKCS password to: " + wholePath) + err := os.WriteFile(wholePath, []byte(pfxPass), 0644) + if err != nil { + log.Println("Error writing file:", err) + } + } + } + + statusLabel.SetText(dnText) + }, *w) + svDialog.Resize(windowSize) + + svDialog.SetFileName(defaultName) + svDialog.SetFilter(storage.NewExtensionFileFilter([]string{".pfx"})) + + svDialog.Show() + }) + + actionWide := container.NewGridWrap( + fyne.NewSize(200, 50), + actionBtn, + ) + + cancelBtn := widget.NewButton("Exit", func() { + log.Println("Quitting...") + app.Quit() + }) + + exitWide := container.NewGridWrap( + fyne.NewSize(200, 50), + cancelBtn, + ) + + bottom := container.NewHBox( + actionWide, // left + layout.NewSpacer(), // flexible space + exitWide, // right + ) + + return bottom +} diff --git a/src/main.go b/src/main.go index 8d4092e..88bee09 100644 --- a/src/main.go +++ b/src/main.go @@ -6,290 +6,63 @@ import ( "image/color" "log" "os" - "path/filepath" - certpair "runesmith/src/modules/certpairs" - "slices" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" - "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/layout" - "fyne.io/fyne/v2/storage" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" ) var ( windowSize fyne.Size = fyne.NewSize(700, 600) + buttonSize fyne.Size = fyne.NewSize(250, 50) + + caChoices = []string{"Sectigo Public Server Authentication CA DV R36", "Sectigo RSA Domain Validation Secure Server CA"} keyTextFilter []string = []string{".key", ".txt", ".pem"} crtTextFilter []string = []string{".crt", ".cer", ".txt", ".pem"} ) func main() { - a := app.NewWithID("nl.systemec.runesmith") - a.Settings().SetTheme(theme.DefaultTheme()) + app := app.NewWithID("nl.systemec.runesmith") + app.Settings().SetTheme(theme.DefaultTheme()) - w := a.NewWindow("RuneSmith") + w := app.NewWindow("RuneSmith") w.Resize(windowSize) - var keyPath, certPath, caIssuer string + var keyPath, certPath, caIssuerChoice string var writePassDown, overwritePassDown bool // Needs to be rendered early! // Certificate Intermediate selector // Basic in form but can easily be expanded. - var caChoices = []string{"Sectigo Public Server Authentication CA DV R36", "Sectigo RSA Domain Validation Secure Server CA"} - var sectigo2025 bool - caRadio := widget.NewRadioGroup(caChoices, func(selected string) { - switch selected { - case "Sectigo Public Server Authentication CA DV R36": - log.Println("Sectigo Public Server Authentication CA DV R36") - sectigo2025 = true - case "Sectigo RSA Domain Validation Secure Server CA": - log.Println("Sectigo RSA Domain Validation Secure Server CA") - sectigo2025 = false - default: //Fallback - sectigo2025 = true - } - }) - - // Labels to show selected filenames - fileLabel1 := widget.NewLabel("No file selected") - fileLabel2 := widget.NewLabel("No file selected") - - radioLabel1 := widget.NewLabel("If needed you can override the selection.\nOtherwise let the application decide.") - - // Certificate Keyfile - keyBtn := widget.NewButton("Upload Private Key File", func() { - keyDiag := dialog.NewFileOpen(func(r fyne.URIReadCloser, err error) { - defer r.Close() - - if r != nil { - fileLabel1.SetText(r.URI().Name()) - keyPath = r.URI().Path() - } - }, w) - keyFilter := storage.NewExtensionFileFilter(keyTextFilter) - keyDiag.SetFilter(keyFilter) - - keyDiag.Resize(windowSize) - keyDiag.Show() - }) - - keyWide := container.NewGridWrap( - fyne.NewSize(300, 50), - keyBtn, - ) - - // Issuer entry - issuerText := widget.NewLabel("Certificate issuer will appear here...") - issuerText.Selectable = true - - // Certificate file - certBtn := widget.NewButton("Upload Certificate File", func() { - // Use NewFileOpen to get the dialog object - certDiag := dialog.NewFileOpen(func(r fyne.URIReadCloser, err error) { - defer r.Close() - - if r != nil { - fileLabel2.SetText(r.URI().Name()) - certPath = r.URI().Path() - - certData := readFile(certPath) - certObj := parseX509(certData) - caIssuer = certObj.Issuer.CommonName - log.Println("Issuer:", caIssuer) - issuerText.SetText(caIssuer) - - if slices.Contains(caChoices, caIssuer) { - caRadio.SetSelected(caIssuer) - } - } - }, w) - certFilter := storage.NewExtensionFileFilter(crtTextFilter) - certDiag.SetFilter(certFilter) - - // Resize the dialog - certDiag.Resize(windowSize) - certDiag.Show() - }) - - certWide := container.NewGridWrap( - fyne.NewSize(300, 50), - certBtn, - ) - - // Render the overwrite checkfox first since I need its variable/object to disable/enable in the next checkbox (which is visually above this one) - overwriteCheckBox := widget.NewCheck("Overwrite possible existing 'pkcs_password' file", func(checked bool) { - if checked { - log.Println("Checked box: overwrite if file exists.") - overwritePassDown = true - } else { - log.Println("Unchecked box: not overwriting if file exists.") - overwritePassDown = false - } - }) - // Disable the checkbox by default since its reliant on the writeCheckBox - overwriteCheckBox.Disable() - - writeCheckBox := widget.NewCheck("Save password to file", func(checked bool) { - if checked { - log.Println("Checked box: saving to file.") - writePassDown = true - overwriteCheckBox.Enable() - } else { - log.Println("Unchecked box: not saving to file") - writePassDown = false - overwriteCheckBox.Disable() - } - }) - - // Status label, where pfx pass will appear - statusText := widget.NewLabel("Status will appear here...") - statusText.Selectable = true - - actionBtn := widget.NewButton("Generate", func() { - files := []string{keyPath, certPath} - - // The following structure is basic but can easily be expanded to fit more pairs - // 0 = ROOT - // 1 = CA - // As per spec in the certpair module. - var certPair []string - if sectigo2025 { - certPair = certpair.SectigoNewChain - } else { - certPair = certpair.SectigoOldChain - } - - // Check if one of the filepaths is empty - allPresent := true - if slices.Contains(files, "") { - allPresent = false - } - - // Check if all needed file/data is present - if !allPresent { - statusText.SetText("One or more files missing!") - log.Println("One or more files missing!") - return - } - - // Generate the PKCS file with the given data - pfxPass, pfxData := integrityCheckAndGo(keyPath, certPath, certPair[1], certPair[0]) - - // Check if the data returned is OK - if len(pfxData) == 0 || pfxData == nil { - log.Println("Something went wrong while creating the PKCS file...") - statusText.SetText("Something went wrong while creating the PKCS file...") - } - - // Most important dialog next, saving the PKCS somewhere - // We also need to declare some variables because otherwise theyd become out of scope - var desiredPath string - var defaultName string = "certificate_store.pfx" - svDialog := dialog.NewFileSave( - func(writer fyne.URIWriteCloser, err error) { - defer writer.Close() - - desiredPath = writer.URI().Path() - desiredParentPath := filepath.Dir(desiredPath) - - if err != nil { - dialog.ShowError(err, w) - } - if writer == nil { - // User cancelled - } - - _, err = writer.Write(pfxData) - if err != nil { - dialog.ShowError(err, w) - } - - var dnText string = "PKCS file saved to: " + desiredPath + "\nThe password for the generated pkcs file is:\n\n" + pfxPass - - // Write down the PKCS password on the filesystem - if writePassDown { - wholePath := desiredParentPath + "/pkcs_password" - var alreadyExists bool - - if _, err := os.Stat(wholePath); err == nil { - alreadyExists = true - } else if os.IsNotExist(err) { - alreadyExists = false - } else { // Failsafe if something unforeseen happens - alreadyExists = true - } - - if alreadyExists && !overwritePassDown { - log.Println("File already exists and overwrite checkbox is unchecked.") - dnText += "\n\nCAREFUL! PKCS password was NOT written down. File exists! NOT OVERWRITING!" - } else { - log.Println("Writing PKCS password to: " + wholePath) - err := os.WriteFile(wholePath, []byte(pfxPass), 0644) - if err != nil { - log.Println("Error writing file:", err) - } - } - } - - statusText.SetText(dnText) - }, w) - svDialog.Resize(windowSize) - - svDialog.SetFileName(defaultName) - svDialog.SetFilter(storage.NewExtensionFileFilter([]string{".pfx"})) - - svDialog.Show() - }) - - actionWide := container.NewGridWrap( - fyne.NewSize(200, 50), - actionBtn, - ) - - cancelBtn := widget.NewButton("Exit", func() { - log.Println("Quitting...") - a.Quit() - }) - - exitWide := container.NewGridWrap( - fyne.NewSize(200, 50), - cancelBtn, - ) + chainRow, caRadio := drawChainRow(&caIssuerChoice) + selecRow := drawSelecRow(&keyPath, &certPath, &caIssuerChoice, caRadio, &w) + persPassRow := drawPersPassRow(&writePassDown, &overwritePassDown) + statusRow, statusLabel := drawStatusRow() + actionRow := drawActionRow(&keyPath, &certPath, &caIssuerChoice, &writePassDown, &overwritePassDown, statusLabel, &w, app) // CREATE LAYOUTS - bottom := container.NewHBox( - actionWide, // left - layout.NewSpacer(), // flexible space - exitWide, // right - ) - centerContent := container.NewVBox( - container.New(layout.NewGridLayout(2), keyWide, fileLabel1), - container.New(layout.NewGridLayout(2), certWide, fileLabel2), - widget.NewLabel(""), - issuerText, + selecRow, canvas.NewLine(color.Gray{Y: 128}), widget.NewLabel(""), - container.New(layout.NewGridLayout(2), radioLabel1, caRadio), + chainRow, layout.NewSpacer(), // optional flexible space - writeCheckBox, - overwriteCheckBox, + persPassRow, canvas.NewLine(color.Gray{Y: 128}), - statusText, // Add the referenced text container + statusRow, // Add the referenced text container widget.NewLabel(""), // Add empty line for space ) content := container.NewBorder( widget.NewLabel("Select relevant files."), // top - bottom, // bottom - nil, nil, // left, right + actionRow, // bottom + nil, nil, // left, right centerContent, )