Skip to content

Commit

Permalink
Add installation command and string sanitization functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
dz0ny committed Dec 6, 2024
1 parent 4ff32f1 commit 81a9d6b
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 0 deletions.
89 changes: 89 additions & 0 deletions cmd/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package cmd

import (
"fmt"
"os"
"os/exec"
"path/filepath"

"github.com/caarlos0/log"
"github.com/spf13/cobra"
)

const socketContent = `[Unit]
Description=Socket for pareto-linux
[Socket]
ListenStream=/var/run/pareto-linux.sock
SocketMode=0666
Accept=no
[Install]
WantedBy=sockets.target`

func getServiceContent() string {
return fmt.Sprintf(`[Unit]
Description=Service for pareto-linux
Requires=pareto-linux.socket
[Service]
ExecStart=%s
User=root
Group=root
StandardInput=socket
Type=oneshot
RemainAfterExit=no
[Install]
WantedBy=multi-user.target`, os.Args[0])
}

var installCmd = &cobra.Command{
Use: "install",
Short: "install root helper",
Run: func(cmd *cobra.Command, args []string) {
installSystemdHelper()
},
}

func init() {
rootCmd.AddCommand(installCmd)
}

func installSystemdHelper() {
systemdPath := "/etc/systemd/system"

//ensure the user is root
if os.Geteuid() != 0 {
log.Fatal("This command must be run as root")
return
}

// Create socket file
socketPath := filepath.Join(systemdPath, "pareto-linux.socket")
if err := os.WriteFile(socketPath, []byte(socketContent), 0644); err != nil {
log.Infof("Failed to create socket file: %v\n", err)
return
}

// Create service file
servicePath := filepath.Join(systemdPath, "[email protected]")
if err := os.WriteFile(servicePath, []byte(getServiceContent()), 0644); err != nil {
fmt.Printf("Failed to create service file: %v\n", err)
return
}

// Execute commands
if err := exec.Command("systemctl", "daemon-reload").Run(); err != nil {
log.Infof("Failed to reload systemd: %v\n", err)
return
}
if err := exec.Command("systemctl", "enable", "pareto-linux.socket").Run(); err != nil {
log.Infof("Failed to enable socket: %v\n", err)
return
}
if err := exec.Command("systemctl", "start", "pareto-linux.socket").Run(); err != nil {
log.Infof("Failed to start socket: %v\n", err)
return
}
}
35 changes: 35 additions & 0 deletions shared/string.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package shared

// Sanitize takes a string and returns a sanitized version containing only ASCII characters.
// It converts non-ASCII characters to underscores and keeps only alphanumeric characters
// and select punctuation marks (., !, -, ', ", _, ,).
func Sanitize(s string) string {
// Convert to ASCII
ascii := make([]byte, len(s))
for i, r := range s {
if r < 128 {
ascii[i] = byte(r)
} else {
ascii[i] = '_'
}
}

// Filter allowed characters
allowed := func(r byte) bool {
return (r >= 'a' && r <= 'z') ||
(r >= 'A' && r <= 'Z') ||
(r >= '0' && r <= '9') ||
r == '.' || r == '!' || r == '-' ||
r == '\'' || r == '"' || r == '_' ||
r == ','
}

result := make([]byte, 0, len(ascii))
for _, c := range ascii {
if allowed(c) {
result = append(result, c)
}
}

return string(result)
}
27 changes: 27 additions & 0 deletions shared/string_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package shared

import (
"testing"
)

func TestSanitize(t *testing.T) {
tests := []struct {
input string
expected string
}{
{"Hello, 世界!", "Hello,_!"},
{"123 ABC abc", "123 ABC abc"},
{"Special chars: @#$%^&*()", "Special chars: _"},
{"Mixed: 你好, 世界! 123", "Mixed: __,_! 123"},
{"Punctuation: .,!-_'\"", "Punctuation: .,!-_'\""},
}

for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
result := Sanitize(test.input)
if result != test.expected {
t.Errorf("Sanitize(%q) = %q; want %q", test.input, result, test.expected)
}
})
}
}

0 comments on commit 81a9d6b

Please sign in to comment.