Skip to content

Commit dd7a4e5

Browse files
authored
Merge pull request #10 from typomedia/v0.2.1
v0.2.1
2 parents b99d0b5 + c0b882a commit dd7a4e5

File tree

39 files changed

+1209
-319
lines changed

39 files changed

+1209
-319
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
.vscode/
33
dist/
44
*.boltdb
5-
tmp/
5+
tmp/
6+
/vendor/

app/app.go

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,79 @@
11
package app
22

3+
import (
4+
"github.com/typomedia/patchouli/app/store/boltdb"
5+
"github.com/typomedia/patchouli/app/structs"
6+
)
7+
38
var app *Application
49

510
type Application struct {
6-
Name string
7-
Version string
8-
Author string
9-
Description string
10-
MailTemplate string
11+
Name string
12+
Version string
13+
Author string
14+
Description string
15+
MailTemplate string
16+
NotifyTemplate string
17+
Config structs.Config
1118
}
1219

1320
func new() *Application {
1421
app = &Application{}
1522
app.Name = "Patchouli"
16-
app.Version = "0.2.0"
23+
app.Version = "0.2.1"
1724
app.Author = "Philipp Speck <[email protected]>"
1825
app.Description = "Patch Management Planner"
26+
err := app.LoadConfig()
27+
if err != nil {
28+
panic(err)
29+
}
30+
if app.Config.Security.Generated {
31+
err = app.StoreConfig()
32+
if err != nil {
33+
panic(err)
34+
}
35+
}
1936

2037
return app
2138
}
39+
40+
func (app *Application) StoreConfig() error {
41+
db := boltdb.New()
42+
defer db.Close()
43+
44+
err := db.SetBucket("config")
45+
if err != nil {
46+
return err
47+
}
48+
49+
err = db.Set("main", app.Config, "config")
50+
if err != nil {
51+
return err
52+
}
53+
54+
return nil
55+
}
56+
57+
func (app *Application) LoadConfig() error {
58+
db := boltdb.New()
59+
defer db.Close()
60+
61+
config, err := db.GetConfig()
62+
if err != nil {
63+
return err
64+
}
65+
66+
if !config.Security.Generated {
67+
err = config.GenerateCipherKey()
68+
if err != nil {
69+
return err
70+
}
71+
}
72+
73+
app.Config = config
74+
return nil
75+
}
76+
2277
func GetApp() *Application {
2378
if app == nil {
2479
app = new()

app/encryption/encryption.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package encryption
2+
3+
import (
4+
"crypto/aes"
5+
"crypto/cipher"
6+
"crypto/rand"
7+
"encoding/hex"
8+
"errors"
9+
"fmt"
10+
"github.com/typomedia/patchouli/app"
11+
"io"
12+
)
13+
14+
func EncryptString(stringToEncrypt string) (string, error) {
15+
key, err := app.GetApp().Config.GetCipherKey()
16+
if err != nil {
17+
return "", err
18+
}
19+
aesKey, _ := hex.DecodeString(key)
20+
plaintext := []byte(stringToEncrypt)
21+
block, err := aes.NewCipher(aesKey)
22+
if err != nil {
23+
return "", err
24+
}
25+
aesGCM, err := cipher.NewGCM(block)
26+
if err != nil {
27+
return "", err
28+
}
29+
30+
nonce := make([]byte, aesGCM.NonceSize())
31+
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
32+
return "", err
33+
}
34+
35+
ciphertext := aesGCM.Seal(nonce, nonce, plaintext, nil)
36+
return fmt.Sprintf("%x", ciphertext), nil
37+
}
38+
39+
func DecryptString(encString string) (string, error) {
40+
key, err := app.GetApp().Config.GetCipherKey()
41+
42+
aesKey, _ := hex.DecodeString(key)
43+
enc, _ := hex.DecodeString(encString)
44+
block, err := aes.NewCipher(aesKey)
45+
if err != nil {
46+
return "", err
47+
}
48+
49+
aesGCM, err := cipher.NewGCM(block)
50+
if err != nil {
51+
return "", err
52+
}
53+
nonceSize := aesGCM.NonceSize()
54+
if len(enc) < nonceSize {
55+
return "", errors.New("ciphertext too short")
56+
}
57+
nonce, ciphertext := enc[:nonceSize], enc[nonceSize:]
58+
plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil)
59+
if err != nil {
60+
return "", err
61+
}
62+
63+
return string(plaintext), nil
64+
}

app/handler/config/edit.go

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,16 @@
11
package config
22

33
import (
4+
"fmt"
45
"github.com/gofiber/fiber/v2"
5-
"github.com/typomedia/patchouli/app/store/boltdb"
6-
"github.com/typomedia/patchouli/app/structs"
7-
"golang.org/x/crypto/bcrypt"
6+
"github.com/typomedia/patchouli/app"
87
)
98

109
func Edit(c *fiber.Ctx) error {
11-
db := boltdb.New()
12-
13-
err := db.SetBucket("config")
14-
if err != nil {
15-
return err
16-
}
17-
18-
var config structs.Config
19-
db.Get("main", &config, "config")
20-
if config.Smtp.Password != "" {
21-
passwordHash, err := bcrypt.GenerateFromPassword([]byte(config.Smtp.Password), bcrypt.DefaultCost)
22-
if err != nil {
23-
return err
24-
}
25-
config.Smtp.Password = string(passwordHash)
10+
config := app.GetApp().Config
11+
if config.General.Hostname == "" {
12+
config.General.Hostname = fmt.Sprintf("%s://%s", c.Protocol(), c.Hostname())
2613
}
27-
defer db.Close()
2814
return c.Render("app/views/config/edit", fiber.Map{
2915
"Config": config,
3016
})

app/handler/config/save.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package config
33
import (
44
"github.com/gofiber/fiber/v2"
55
"github.com/gofiber/fiber/v2/log"
6+
"github.com/typomedia/patchouli/app"
7+
"github.com/typomedia/patchouli/app/encryption"
68
"github.com/typomedia/patchouli/app/store/boltdb"
79
"github.com/typomedia/patchouli/app/structs"
810
)
@@ -20,8 +22,21 @@ func Save(c *fiber.Ctx) error {
2022
log.Error(err)
2123
}
2224

25+
// update config from body with security params from app
26+
config.Security = app.GetApp().Config.Security
27+
28+
_, err = encryption.DecryptString(config.Smtp.Password)
29+
if err != nil { // config.Smtp.Password is not encrypted, encrypt it
30+
config.Smtp.Password, err = encryption.EncryptString(config.Smtp.Password)
31+
if err != nil {
32+
log.Error(err)
33+
}
34+
}
35+
2336
db.Set("main", config, "config")
2437

38+
app.GetApp().Config = config
39+
2540
defer db.Close()
2641

2742
return c.Redirect("/config")
Lines changed: 8 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,29 @@
11
package filter
22

33
import (
4-
"encoding/json"
5-
"sort"
6-
"time"
7-
84
"github.com/gofiber/fiber/v2"
9-
"github.com/gofiber/fiber/v2/log"
10-
"github.com/typomedia/patchouli/app/helper"
115
"github.com/typomedia/patchouli/app/store/boltdb"
126
"github.com/typomedia/patchouli/app/structs"
137
)
148

159
func Operator(c *fiber.Ctx) error {
16-
id := c.Params("id")
10+
operatorId := c.Params("id")
1711
db := boltdb.New()
12+
defer db.Close()
1813

19-
err := db.SetBucket("machine")
14+
machines, err := db.GetActiveMachines()
2015
if err != nil {
2116
return err
2217
}
2318

24-
machines, _ := db.GetAllByOperatorId(id, "machine")
25-
26-
Machines := structs.Machines{}
27-
for _, v := range machines {
28-
machine := structs.Machine{}
29-
err = json.Unmarshal(v, &machine)
30-
if err != nil {
31-
return err
19+
var operatorMachines structs.Machines
20+
for _, m := range machines {
21+
if m.Operator.Id == operatorId {
22+
operatorMachines = append(operatorMachines, m)
3223
}
33-
34-
lastUpdate, _ := db.GetLastByName(machine.Id, "history")
35-
36-
update := structs.Update{}
37-
err = json.Unmarshal(lastUpdate, &update)
38-
if err != nil {
39-
log.Error(err)
40-
}
41-
42-
machine.Update = update
43-
44-
Machines = append(Machines, machine)
45-
46-
}
47-
48-
// sort machines by oldest update first
49-
sort.Sort(structs.ByDate(Machines))
50-
51-
err = db.SetBucket("config")
52-
if err != nil {
53-
return err
5424
}
5525

56-
var config structs.Config
57-
db.Get("main", &config, "config")
58-
59-
defer db.Close()
60-
61-
interval := config.General.Interval
62-
for i := range Machines {
63-
currentDate := time.Now()
64-
65-
if Machines[i].Update.Date == "" {
66-
Machines[i].Update.Date = "0000-00-00"
67-
Machines[i].Status = "danger"
68-
continue
69-
}
70-
71-
Machines[i].Update.Date = helper.UnixToDateString(Machines[i].Update.Date)
72-
73-
date, err := time.Parse("2006-01-02", Machines[i].Update.Date)
74-
if err != nil {
75-
log.Error(err)
76-
}
77-
78-
Machines[i].Days = int(currentDate.Sub(date).Hours() / 24)
79-
if Machines[i].Days > interval {
80-
Machines[i].Status = "danger"
81-
} else if Machines[i].Days > interval/3 {
82-
Machines[i].Status = "warning"
83-
} else {
84-
Machines[i].Status = "success"
85-
}
86-
Machines[i].Days = interval - int(currentDate.Sub(date).Hours()/24)
87-
88-
}
8926
return c.Render("app/views/dashboard/list", fiber.Map{
90-
"Machines": Machines,
27+
"Machines": operatorMachines,
9128
})
9229
}

0 commit comments

Comments
 (0)