adding packages crypt & db + amend echo sys & util

This commit is contained in:
Mahdi Abu Yasmine 2023-11-04 17:33:24 +01:00
parent a15a1b74a4
commit 6a5875b94c
7 changed files with 455 additions and 4 deletions

60
crypt/crypt.go Normal file
View File

@ -0,0 +1,60 @@
package crypt
import (
"crypto/cipher"
"crypto/rand"
"log"
"golang.org/x/crypto/chacha20poly1305"
)
type Crypt struct {
key []byte
ads []byte
aead cipher.AEAD
}
func NewChacha20poly1305Key() []byte {
k := make([]byte, chacha20poly1305.KeySize)
if _, err := rand.Read(k); err != nil {
panic(err)
}
return k
}
func NewCrypt(key []byte, ads []byte) *Crypt {
if len(key) == 0 {
// log.Printf(" == GENERATE NEW KEY ==\n")
key = NewChacha20poly1305Key()
}
aead, err := chacha20poly1305.New(key)
if err != nil {
panic(err)
}
return &Crypt{key: key, ads: ads, aead: aead}
}
func (c *Crypt) GenNonce(length int) []byte {
nonce := make([]byte, c.aead.NonceSize(), c.aead.NonceSize()+length+c.aead.Overhead())
if _, err := rand.Read(nonce); err != nil {
panic(err)
}
return nonce
}
func (c *Crypt) Encrypt(msg []byte) []byte {
nonce := c.GenNonce(len(msg))
encryptedMsg := c.aead.Seal(nonce, nonce, msg, c.ads)
return encryptedMsg
}
func (c *Crypt) Decrypt(encrypted []byte) ([]byte, bool) {
done := true
nonce, ciphertext := encrypted[:c.aead.NonceSize()], encrypted[c.aead.NonceSize():]
plaintext, err := c.aead.Open(nil, nonce, ciphertext, c.ads)
if err != nil {
done = false
log.Printf(" error decrypt data : %v\n", err)
}
return plaintext, done
}

171
db/db.go Normal file
View File

@ -0,0 +1,171 @@
package db
import (
"database/sql"
"fmt"
"log"
"time"
"gitea.meta-tech.academy/go/core/util"
"github.com/go-sql-driver/mysql"
)
const USER_DEFAULT_PRIVILEGES = "CREATE, CREATE VIEW, CREATE TEMPORARY TABLES, SELECT, INSERT, UPDATE, DELETE, EXECUTE, LOCK TABLES, TRIGGER"
var MAX_OPEN_CONNS = 500
var MAX_IDLE_CONNS = 0
type Db struct {
pool map[string]*sql.DB
}
type DbConfig struct {
host string
dbname string
user string
passwd string
port int
}
type PasswordDecode func(in string) (string, bool)
func (dbc *DbConfig) GetHost() string {
return fmt.Sprintf("%s:%d", dbc.host, dbc.port)
}
func (dbc *DbConfig) GetSqlConfig(passwdGet ...PasswordDecode) *mysql.Config {
var plain string = dbc.passwd
var done bool = len(passwdGet) == 0
if !done {
plain, done = passwdGet[0](dbc.passwd)
}
if done {
return &mysql.Config{
User: dbc.user,
Net: "tcp",
Addr: dbc.GetHost(),
DBName: dbc.dbname,
Passwd: plain,
AllowNativePasswords: true,
}
} else {
fmt.Printf("invalid password unable to connect")
time.Sleep(3 * time.Second)
}
return nil
}
func (dbc *DbConfig) NewDbConfig(host string, dbname string, user string, passwd string, port int) *DbConfig {
return &DbConfig{host, dbname, user, passwd, port}
}
func (db *Db) AddDb(dbconf *DbConfig, passwdGet ...PasswordDecode) {
cnx, err := sql.Open("mysql", dbconf.GetSqlConfig(passwdGet...).FormatDSN())
if err != nil {
log.Fatal(err)
}
pingErr := cnx.Ping()
if pingErr != nil {
log.Fatal(pingErr)
}
cnx.SetMaxIdleConns(MAX_IDLE_CONNS)
cnx.SetMaxOpenConns(MAX_OPEN_CONNS)
db.pool[dbconf.dbname] = cnx
}
func NewDb() *Db {
pool := make(map[string]*sql.DB)
return &Db{pool}
}
func getFullUser(username string, hostname string) string {
return fmt.Sprintf("'%s'@'%s'", util.EscapeSquote(username), util.EscapeSquote(hostname))
}
func (db *Db) onDbExec(dbname string, instr DbInstruct) bool {
var done bool
if sqlDb, ok := db.pool[dbname]; ok {
return instr(sqlDb)
} else {
fmt.Printf("you should add db mysql first\n")
done = ok
}
return done
}
type DbInstruct func(database *sql.DB) bool
func (db *Db) CreateUser(username string, hostname string, passwd string) bool {
return db.onDbExec("mysql", func(sqlDb *sql.DB) bool {
query := fmt.Sprintf(
"CREATE USER IF NOT EXISTS %s IDENTIFIED BY '%s';",
getFullUser(username, hostname),
util.EscapeSquote(passwd),
)
_, err := sqlDb.Exec(query)
done := err == nil
if !done {
fmt.Printf("unable to add user %s\n%v\n", username, err)
}
return done
})
}
func (db *Db) GrantUserPrivileges(dbname string, username string, hostname string) bool {
return db.onDbExec("mysql", func(sqlDb *sql.DB) bool {
query := fmt.Sprintf(
"GRANT %s ON `%s`.* TO %s;",
USER_DEFAULT_PRIVILEGES,
util.EscapeBt(dbname),
getFullUser(username, hostname),
)
_, err := sqlDb.Exec(query)
done := err == nil
if !done {
fmt.Printf("query : %s\n", query)
fmt.Printf("unable to grant user privilege %s\n%v\n", username, err)
}
return done
})
}
func (db *Db) CreateDb(dbname string, collate string) bool {
return db.onDbExec("mysql", func(sqlDb *sql.DB) bool {
query := fmt.Sprintf(
"CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET '%s' COLLATE '%s_unicode_ci'",
util.EscapeBt(dbname),
util.EscapeSquote(collate),
util.EscapeSquote(collate),
)
_, err := db.pool["mysql"].Exec(query)
done := err == nil
if !done {
fmt.Printf("unable to create database %s\n%v\n", dbname, err)
}
return done
})
}
func (db *Db) SizeDb(dbname string) float32 {
type RsSize struct {
Dbname string
Size float32
}
rs := RsSize{Size: -1}
db.onDbExec("information_schema", func(sqlDb *sql.DB) bool {
query := "SELECT table_schema 'dbname', SUM(data_length + index_length)/1024/1024 'size' FROM TABLES WHERE table_schema = ? GROUP BY table_schema;"
row := sqlDb.QueryRow(query, dbname)
err := row.Scan(&rs.Dbname, &rs.Size)
done := err != nil
if !done {
if err == sql.ErrNoRows {
fmt.Printf(" cannot find db %s or db is empty\n", dbname)
} else {
fmt.Printf(" what the fuck error : %+v\n", err)
}
}
return done
})
return rs.Size
}

View File

@ -10,10 +10,11 @@ import (
var curStyles *style.Styles
var hasCurStyle bool = false
var msgUninit = "Missing current *style.Styles, you should call echo.SetCurrentStyles(styles *style.Styles) first"
func Cstyle(name string) *style.Style {
if !hasCurStyle {
panic("Missing current style, you should call style.SetCurrentStyles(styles *style.Styles) first\n")
panic(msgUninit)
}
return curStyles.Get(name)
}
@ -63,6 +64,13 @@ func State(done bool) {
Ln()
}
func Keyval(key string, val string, names ...string) {
if !hasCurStyle {
panic(msgUninit)
}
curStyles.Keyval(key, val, names...)
}
func Msg(msg string) {
fmt.Printf("%s%s\n", strings.Repeat(" ", 4), msg)
}

6
go.mod
View File

@ -3,8 +3,12 @@ module gitea.meta-tech.academy/go/core
go 1.20
require (
github.com/go-sql-driver/mysql v1.7.1
github.com/gookit/color v1.5.4
golang.org/x/sys v0.13.0
github.com/ulikunitz/xz v0.5.11
golang.org/x/crypto v0.14.0
golang.org/x/sys v0.14.0
golang.org/x/text v0.14.0
gopkg.in/yaml.v3 v3.0.1
)

12
go.sum
View File

@ -1,12 +1,20 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

132
sys/xtract.go Normal file
View File

@ -0,0 +1,132 @@
package sys
import (
"archive/zip"
"bufio"
"bytes"
"compress/bzip2"
"compress/gzip"
"fmt"
"io"
"log"
"os"
"github.com/ulikunitz/xz"
)
type Xtract struct {
dir string
reader *bufio.Reader
bar *io.Writer
outFile string
withBar bool
}
func NewXtract(dir string, outFile string) *Xtract {
return &Xtract{dir: dir, outFile: outFile, withBar: false}
}
func (x *Xtract) addBar(bar *io.Writer) {
x.bar = bar
x.withBar = true
}
func (x *Xtract) setCompressedFile(dumpName string) {
path := fmt.Sprintf("%s/%s", x.dir, dumpName)
file, err := os.Open(path)
if err != nil {
panic(err)
}
x.reader = bufio.NewReader(file)
}
func (x *Xtract) writeUncompressedData(out *bytes.Buffer) bool {
err := os.WriteFile(x.outFile, out.Bytes(), 0644)
if err != nil {
panic(err)
}
return true
}
func (x *Xtract) UnGzip(dumpName string) bool {
x.setCompressedFile(dumpName)
var out bytes.Buffer
r, err := gzip.NewReader(x.reader)
if err != nil {
panic(err)
}
if x.withBar {
_, err = io.Copy(io.MultiWriter(&out, *x.bar), r)
} else {
_, err = io.Copy(&out, r)
}
if err != nil {
panic(err)
}
// if x.withBar {
// x.bar.Clear()
// }
return x.writeUncompressedData(&out)
}
func (x *Xtract) UnBz2(dumpName string) bool {
x.setCompressedFile(dumpName)
var out bytes.Buffer
r := bzip2.NewReader(x.reader)
var err error
if x.withBar {
_, err = io.Copy(io.MultiWriter(&out, *x.bar), r)
} else {
_, err = io.Copy(&out, r)
}
if err != nil {
panic(err)
}
return x.writeUncompressedData(&out)
}
func (x *Xtract) UnXz(dumpName string) bool {
x.setCompressedFile(dumpName)
var out bytes.Buffer
r, err := xz.NewReader(x.reader)
if err != nil {
panic(err)
}
if x.withBar {
_, err = io.Copy(io.MultiWriter(&out, *x.bar), r)
} else {
_, err = io.Copy(&out, r)
}
if err != nil {
panic(err)
}
return x.writeUncompressedData(&out)
}
func (x *Xtract) UnZip(dumpName string) bool {
var done bool = false
path := fmt.Sprintf("%s/%s", x.dir, dumpName)
r, err := zip.OpenReader(path)
if err != nil {
panic(err)
}
defer r.Close()
if len(r.File) > 0 {
rc, err := r.File[0].Open()
if err != nil {
log.Fatal(err)
}
var out bytes.Buffer
if x.withBar {
_, err = io.Copy(io.MultiWriter(&out, *x.bar), rc)
} else {
_, err = io.Copy(&out, rc)
}
if err != nil {
log.Fatal(err)
}
rc.Close()
done = x.writeUncompressedData(&out)
}
return done
}

View File

@ -1,8 +1,17 @@
package util
import (
"bytes"
"encoding/hex"
"fmt"
"log"
"math"
"path"
"strconv"
"strings"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
func PrependToSliceStr(strs *[]string, prefix string) {
@ -38,3 +47,62 @@ func CastStrings2ints(strs *[]string) []int {
}
return a
}
func PrettyByteSize(b int64) string {
bf := float64(b)
for _, unit := range []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"} {
if math.Abs(bf) < 1024.0 {
return fmt.Sprintf("%3.2f%s", bf, unit)
}
bf /= 1024.0
}
return fmt.Sprintf("%.2fYi", bf)
}
func Ucfirst(str *string) {
caser := cases.Title(language.English)
*str = caser.String(*str)
}
func RemoveExtension(fileName string) string {
return strings.TrimSuffix(fileName, path.Ext(fileName))
}
func GetBytesAsHex(key []byte) []byte {
dst := make([]byte, hex.EncodedLen(len(key)))
hex.Encode(dst, key)
return dst
}
func GetBytesFromHex(key []byte) []byte {
dst := make([]byte, hex.DecodedLen(len(key)))
n, err := hex.Decode(dst, key)
if err != nil {
log.Fatal(err)
}
return dst[:n]
}
func Escape(str string, c rune) string {
var buf bytes.Buffer
for _, char := range str {
switch char {
case c:
buf.WriteRune('\\')
}
buf.WriteRune(char)
}
return buf.String()
}
func EscapeBt(str string) string {
return Escape(str, '`')
}
func EscapeDquote(str string) string {
return Escape(str, '"')
}
func EscapeSquote(str string) string {
return Escape(str, '\'')
}