adding packages crypt & db + amend echo sys & util
This commit is contained in:
parent
a15a1b74a4
commit
6a5875b94c
60
crypt/crypt.go
Normal file
60
crypt/crypt.go
Normal 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
171
db/db.go
Normal 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
|
||||
}
|
10
echo/echo.go
10
echo/echo.go
|
@ -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
6
go.mod
|
@ -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
12
go.sum
|
@ -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
132
sys/xtract.go
Normal 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
|
||||
}
|
68
util/util.go
68
util/util.go
|
@ -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, '\'')
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user