feat: rewrite parts for readability
All checks were successful
Cross-Compile Binaries / compile-linux (push) Successful in 3m30s
Cross-Compile Binaries / compile-windows (push) Successful in 11m10s

This commit is contained in:
2026-01-29 16:09:17 +01:00
parent 68fda13d0a
commit 581c395a17
2 changed files with 310 additions and 245 deletions

292
src/draw.go Normal file
View File

@@ -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
}

View File

@@ -6,290 +6,63 @@ import (
"image/color" "image/color"
"log" "log"
"os" "os"
"path/filepath"
certpair "runesmith/src/modules/certpairs"
"slices"
"fyne.io/fyne/v2" "fyne.io/fyne/v2"
"fyne.io/fyne/v2/app" "fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container" "fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget" "fyne.io/fyne/v2/widget"
) )
var ( var (
windowSize fyne.Size = fyne.NewSize(700, 600) 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"} keyTextFilter []string = []string{".key", ".txt", ".pem"}
crtTextFilter []string = []string{".crt", ".cer", ".txt", ".pem"} crtTextFilter []string = []string{".crt", ".cer", ".txt", ".pem"}
) )
func main() { func main() {
a := app.NewWithID("nl.systemec.runesmith") app := app.NewWithID("nl.systemec.runesmith")
a.Settings().SetTheme(theme.DefaultTheme()) app.Settings().SetTheme(theme.DefaultTheme())
w := a.NewWindow("RuneSmith") w := app.NewWindow("RuneSmith")
w.Resize(windowSize) w.Resize(windowSize)
var keyPath, certPath, caIssuer string var keyPath, certPath, caIssuerChoice string
var writePassDown, overwritePassDown bool var writePassDown, overwritePassDown bool
// Needs to be rendered early! // Needs to be rendered early!
// Certificate Intermediate selector // Certificate Intermediate selector
// Basic in form but can easily be expanded. // 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"} chainRow, caRadio := drawChainRow(&caIssuerChoice)
var sectigo2025 bool selecRow := drawSelecRow(&keyPath, &certPath, &caIssuerChoice, caRadio, &w)
caRadio := widget.NewRadioGroup(caChoices, func(selected string) { persPassRow := drawPersPassRow(&writePassDown, &overwritePassDown)
switch selected { statusRow, statusLabel := drawStatusRow()
case "Sectigo Public Server Authentication CA DV R36": actionRow := drawActionRow(&keyPath, &certPath, &caIssuerChoice, &writePassDown, &overwritePassDown, statusLabel, &w, app)
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,
)
// CREATE LAYOUTS // CREATE LAYOUTS
bottom := container.NewHBox(
actionWide, // left
layout.NewSpacer(), // flexible space
exitWide, // right
)
centerContent := container.NewVBox( centerContent := container.NewVBox(
container.New(layout.NewGridLayout(2), keyWide, fileLabel1), selecRow,
container.New(layout.NewGridLayout(2), certWide, fileLabel2),
widget.NewLabel(""),
issuerText,
canvas.NewLine(color.Gray{Y: 128}), canvas.NewLine(color.Gray{Y: 128}),
widget.NewLabel(""), widget.NewLabel(""),
container.New(layout.NewGridLayout(2), radioLabel1, caRadio), chainRow,
layout.NewSpacer(), // optional flexible space layout.NewSpacer(), // optional flexible space
writeCheckBox, persPassRow,
overwriteCheckBox,
canvas.NewLine(color.Gray{Y: 128}), 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 widget.NewLabel(""), // Add empty line for space
) )
content := container.NewBorder( content := container.NewBorder(
widget.NewLabel("Select relevant files."), // top widget.NewLabel("Select relevant files."), // top
bottom, // bottom actionRow, // bottom
nil, nil, // left, right nil, nil, // left, right
centerContent, centerContent,
) )