Skip to content

Commit

Permalink
Merge branch 'feature/localizator'
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikhail Borovikov committed Nov 5, 2021
2 parents dad82c4 + 55e68f1 commit d585ecc
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 19 deletions.
12 changes: 12 additions & 0 deletions cmd/locales/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"delete_resp_wrong_index": "Wrong index. Need enter command to format as <code>/delete 7</code>",
"delete_unable_delete": "Unable to delete the secret",
"delete_secrete_deleted": "The secret deleted",
"query_no_secrets": "No secrets found",
"setpass_unable_set": "Unable to set master password",
"setpass_empty_pass": "Master password cannot be empty. Example of a valid command: <code>/setpass your_new_master_pass</code>",
"setpasspass_setted": "Master password setted",
"add_resp_command": "Please enter your description, login and password separated by newline:",
"checkpass_please_enter_pass": "Please enter a master password:",
"setpass_pass_changed": "Master password susccessful changed"
}
12 changes: 12 additions & 0 deletions cmd/locales/ru.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"delete_resp_wrong_index": "Неправильный индекс. Введите команду как в примере: <code>/delete 7</code>",
"delete_unable_delete": "Не удалось удалить секрет",
"delete_secrete_deleted": "Секрет удален",
"query_no_secrets": "Секреты не найдены",
"setpass_unable_set": "Не удалось установить мастер пароль",
"setpass_empty_pass": "Мастер пароль не может быть пустым. Пример правильной комманды: <code>/setpass your_new_master_pass</code>",
"setpasspass_setted": "Мастер пароль установлен",
"add_resp_command": "Пожалуйста введите описание, пользователя и пароль, разделив их новой строкой:",
"checkpass_please_enter_pass": "Пожалуйста введите мастер пароль:",
"setpass_pass_changed": "Мастер пароль успешно изменен"
}
16 changes: 15 additions & 1 deletion cmd/secretable.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
package main

import (
"embed"
"fmt"
"os"
"strings"
"time"

"secretable/pkg/crypto"
"secretable/pkg/handlers"
"secretable/pkg/localizator"
"secretable/pkg/log"
"secretable/pkg/tables"

Expand Down Expand Up @@ -61,6 +64,9 @@ var cmds = []tb.Command{
},
}

//go:embed locales
var localesFS embed.FS

func main() {
_, err := flags.Parse(&opts)
if flags.WroteHelp(err) {
Expand All @@ -72,6 +78,7 @@ func main() {
}

log.Info("⏳ Initialization Secretable")

log.Info("📝 Google credentials: " + opts.GoogleCredentials)
log.Info("📄 Spreadsheet ID: " + opts.SpreadsheetID)
log.Info("🧹 Cleanup timeout: " + fmt.Sprint(opts.CleanupTime, " sec"))
Expand All @@ -87,6 +94,13 @@ func main() {
}
}

locales := new(localizator.Localizator)
if err = locales.InitFromFS(localesFS, "locales"); err != nil {
log.Fatal("Initialization locales: " + err.Error())
}

log.Info("🌎 Supported locales: " + strings.Join(locales.GetLocales(), ", "))

tableProvider, err := tables.NewTablesProvider(opts.GoogleCredentials, opts.SpreadsheetID)
if err != nil {
log.Fatal("Unable to create tables provider: " + err.Error())
Expand All @@ -110,7 +124,7 @@ func main() {
log.Fatal("Unable to create new bot instance: " + err.Error())
}

handler := handlers.NewHandler(b, tableProvider, opts.CleanupTime, !opts.Unencrypted)
handler := handlers.NewHandler(b, tableProvider, locales, opts.CleanupTime, !opts.Unencrypted)

startMessage := "Welcome! Just enter text into the chat to find secrets or use the commands:\n\n"
for _, cmd := range cmds {
Expand Down
29 changes: 16 additions & 13 deletions pkg/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"math/rand"
"os"
"secretable/pkg/crypto"
"secretable/pkg/localizator"
"secretable/pkg/log"
"secretable/pkg/tables"
"strconv"
Expand Down Expand Up @@ -48,18 +49,20 @@ type Handler struct {
waitmpstates sync.Map
b *tb.Bot
tp *tables.TablesProvider
locales *localizator.Localizator
}

func NewHandler(b *tb.Bot, tp *tables.TablesProvider, cleanupTime int, enc bool) *Handler {
func NewHandler(b *tb.Bot, tp *tables.TablesProvider, locales *localizator.Localizator, cleanupTime int, enc bool) *Handler {
return &Handler{
b: b, tp: tp, cleanupTime: cleanupTime, encMode: enc,
b: b, tp: tp, locales: locales,
cleanupTime: cleanupTime, encMode: enc,
}
}

func (h *Handler) Delete(m *tb.Message) {
index, err := strconv.Atoi(strings.TrimSpace(strings.TrimPrefix(m.Text, "/delete")))
if err != nil {
sendMessage(m, h.b, "Wrong index. Need enter command to format as <code>/delete 7</code>")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "delete_resp_wrong_index"))
return
}

Expand All @@ -70,11 +73,11 @@ func (h *Handler) Delete(m *tb.Message) {
}

if err != nil {
sendMessage(m, h.b, "Unable to delete the secret")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "delete_unable_delete"))
return
}

sendMessage(m, h.b, "The secret deleted")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "delete_secret_deleted"))

}

Expand Down Expand Up @@ -128,7 +131,7 @@ func (h *Handler) query(m *tb.Message) {
}

if !ok {
sendMessage(m, h.b, "No secrets found")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "query_no_secrets"))
}
}

Expand Down Expand Up @@ -177,7 +180,7 @@ func (h *Handler) queryEncrypted(m *tb.Message) {
}

if !ok {
sendMessage(m, h.b, "No secrets found")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "query_no_secrets"))
}
}

Expand All @@ -189,13 +192,13 @@ func (h *Handler) ResetPass(m *tb.Message) {
data := strings.TrimSpace(strings.TrimPrefix(m.Text, "/setpass"))

if data == "" {
sendMessage(m, h.b, "Master password cannot be empty. Example of a valid command: <code>/setpass your_new_master_pass</code>")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpass_empty_pass"))
return
}

privkeyBytes, ok, err := getPrivkeyAsBytes(h.b, h.tp, m, h.mastePass)
if err != nil || !ok {
sendMessage(m, h.b, "Unable to set master password")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpass_unable_set"))
return
}

Expand All @@ -206,24 +209,24 @@ func (h *Handler) ResetPass(m *tb.Message) {
cypher, err := crypto.EncryptWithPhrase([]byte(data), []byte(os.Getenv("ST_SALT")), nonce, privkeyBytes)
if err != nil {
log.Error("Encrypt with password: " + err.Error())
sendMessage(m, h.b, "Unable to set master password")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpass_unable_set"))
return
}

cypher = append(nonce, cypher...)

if err = h.tp.SetKey(base58.Encode(cypher)); err != nil {
log.Error("Store encrypted key to table: " + err.Error())
sendMessage(m, h.b, "Unable to set master password")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpass_unable_set"))
return
}

h.mastePass = data
sendMessage(m, h.b, "Master password setted")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpasspass_setted"))
}

func (h *Handler) Set(m *tb.Message) {
sendMessage(m, h.b, "Please enter your description, login and password separated by newline:")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "add_resp_command"))
h.setstates.Store(m.Chat.ID, true)
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/handlers/middlewares.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (h *Handler) ControlMasterPassMiddleware(use bool, isSetHandler bool, next

if !isSetHandler || isSetHandler && !ok {
h.waitmpstates.Store(m.Chat.ID, true)
sendMessage(m, h.b, "Please enter a master password:")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "checkpass_please_enter_pass"))
return
}

Expand All @@ -76,7 +76,7 @@ func (h *Handler) setPass(m *tb.Message) {
_, ok, err := getPrivkeyAsBytes(h.b, h.tp, m, newMasterPass)
if err != nil {
log.Error("Get private key: " + err.Error())
sendMessage(m, h.b, "Unable to store master password")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpass_unable_set"))
return
}

Expand All @@ -88,7 +88,7 @@ func (h *Handler) setPass(m *tb.Message) {
cypher, err := crypto.EncryptWithPhrase([]byte(newMasterPass), []byte(os.Getenv("ST_SALT")), nonce, binPrivkey)
if err != nil {
log.Error("Encrypt with phrase: " + err.Error())
sendMessage(m, h.b, "Unable to store master password")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpass_unable_set"))
return
}

Expand All @@ -97,14 +97,14 @@ func (h *Handler) setPass(m *tb.Message) {
err = h.tp.SetKey(base58.Encode(cypher))
if err != nil {
log.Error("Store to table: " + err.Error())
sendMessage(m, h.b, "Unable to store master password")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpass_unable_set"))
return
}
}

h.mastePass = newMasterPass

sendMessage(m, h.b, "Master password susccessful setted")
sendMessage(m, h.b, h.locales.Get(m.Sender.LanguageCode, "setpass_pass_changed"))
}

func (h *Handler) ControlSetSecretMiddleware(isSetHandler bool, next func(m *tb.Message)) func(m *tb.Message) {
Expand Down
75 changes: 75 additions & 0 deletions pkg/localizator/localizator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package localizator

import (
"encoding/json"
"fmt"
"io/fs"
"path/filepath"
"secretable/pkg/log"
"strings"
"sync"
)

type Localizator struct {
locales []string
m sync.Map
}

func (l *Localizator) InitFromFS(f fs.FS, basePath string) error {
files, err := fs.ReadDir(f, basePath)
if err != nil {
return fmt.Errorf("read dir: %s", err.Error())
}

for _, file := range files {
if file.IsDir() {
continue
}

target := filepath.Join(basePath, file.Name())
b, err := fs.ReadFile(f, target)
if err != nil {
log.Error("Read file " + target + " :" + err.Error())
continue
}

m := make(map[string]string)

err = json.Unmarshal(b, &m)
if err != nil {
log.Error("Parse JSON " + target + " :" + err.Error())
continue
}

shortlocale := strings.TrimSuffix(file.Name(), ".json")

l.locales = append(l.locales, shortlocale)
for k, v := range m {
l.m.Store(shortlocale+"."+k, v)
}
}

return nil
}

func (l *Localizator) GetLocales() []string {
a := make([]string, len(l.locales))
copy(a, l.locales)
return a
}

func (l *Localizator) Get(locale string, key string) string {
fmt.Println(locale + "." + key)
v, ok := l.m.Load(locale + "." + key)
if !ok {
if locale != "en" {
locale = "en"
v, ok = l.m.Load(locale + "." + key)
}
if !ok {
return ""
}
}

return v.(string)
}

0 comments on commit d585ecc

Please sign in to comment.