fix metagen deps

This commit is contained in:
2025-03-09 16:42:08 -04:00
parent 78cd5cc2bb
commit 963b83534c
10 changed files with 95 additions and 92 deletions

View File

@@ -4,7 +4,7 @@ import (
"crypto/rand"
"errors"
"math/big"
"maxwarden/config"
"maxwarden/constants"
"maxwarden/entries"
"maxwarden/security"
"maxwarden/users"
@@ -28,7 +28,7 @@ type Identity struct {
}
func NewIdentity(userid int32, securityStamp string, masterKey string, rememberMe bool) *Identity {
expirationDuration := time.Duration(time.Hour * 24 * time.Duration(config.IDENTITY_COOKIE_EXPIRY_DAYS))
expirationDuration := time.Duration(time.Hour * 24 * time.Duration(constants.IDENTITY_COOKIE_EXPIRY_DAYS))
expiration := time.Now().Add(expirationDuration)
// hash password input
@@ -63,7 +63,7 @@ func Authenticate(username string, password string) (int32, string, bool) {
user, userErr := users.FetchByUsername(username)
if userErr != nil || user.FailedAttempts > int32(config.MAX_LOGIN_ATTEMPTS) {
if userErr != nil || user.FailedAttempts > int32(constants.MAX_LOGIN_ATTEMPTS) {
// set user password to dummy password to keep timing consistent when validating password
user.Password = "$2a$14$KW5OO1wZqGGq3SrpBFj0Oema5DG8Ph7lZJvq0ECkkYBpNFom6b9vO"
security.ComparePasswords(password, user.Password)
@@ -95,7 +95,7 @@ func Authenticate(username string, password string) (int32, string, bool) {
// }
mk := security.SHA512_58(password)
user.Data, _ = security.EncryptDataWithKey(&secrets, mk)
user.Data, _ = security.EncryptData(&secrets, mk)
}
users.Update(user)
@@ -109,8 +109,8 @@ func CheckPasswordCriteria(password string) error {
return errors.New("Password cannot be blank.")
}
if len(password) < config.PASSWORD_MIN_LENGTH {
return errors.New("Password must be at least " + strconv.Itoa(config.PASSWORD_MIN_LENGTH) + " characters long.")
if len(password) < constants.PASSWORD_MIN_LENGTH {
return errors.New("Password must be at least " + strconv.Itoa(constants.PASSWORD_MIN_LENGTH) + " characters long.")
}
uppercaseCount := 0
@@ -136,20 +136,20 @@ func CheckPasswordCriteria(password string) error {
}
}
if uppercaseCount < config.PASSWORD_REQUIRED_UPPERCASE {
return errors.New("Password must contain at least " + strconv.Itoa(config.PASSWORD_REQUIRED_UPPERCASE) + " uppercase character(s).")
if uppercaseCount < constants.PASSWORD_REQUIRED_UPPERCASE {
return errors.New("Password must contain at least " + strconv.Itoa(constants.PASSWORD_REQUIRED_UPPERCASE) + " uppercase character(s).")
}
if lowercaseCount < config.PASSWORD_REQUIRED_LOWERCASE {
return errors.New("Password must contain at least " + strconv.Itoa(config.PASSWORD_REQUIRED_LOWERCASE) + " lowercase character(s).")
if lowercaseCount < constants.PASSWORD_REQUIRED_LOWERCASE {
return errors.New("Password must contain at least " + strconv.Itoa(constants.PASSWORD_REQUIRED_LOWERCASE) + " lowercase character(s).")
}
if numberCount < config.PASSWORD_REQUIRED_NUMBERS {
return errors.New("Password must contain at least " + strconv.Itoa(config.PASSWORD_REQUIRED_NUMBERS) + " number(s).")
if numberCount < constants.PASSWORD_REQUIRED_NUMBERS {
return errors.New("Password must contain at least " + strconv.Itoa(constants.PASSWORD_REQUIRED_NUMBERS) + " number(s).")
}
if symbolCount < config.PASSWORD_REQUIRED_SYMBOLS {
return errors.New("Password must contain at least " + strconv.Itoa(config.PASSWORD_REQUIRED_SYMBOLS) + " symbol(s).")
if symbolCount < constants.PASSWORD_REQUIRED_SYMBOLS {
return errors.New("Password must contain at least " + strconv.Itoa(constants.PASSWORD_REQUIRED_SYMBOLS) + " symbol(s).")
}
return nil

View File

@@ -20,7 +20,7 @@ func main() {
}
masterKey := security.SHA512_58(os.Args[1])
cryptData, _ := security.EncryptDataWithKey(&testData, masterKey)
cryptData, _ := security.EncryptData(&testData, masterKey)
println(passHash)
println(cryptData)

View File

@@ -10,34 +10,6 @@ import (
"github.com/joho/godotenv"
)
const (
SESSION_COOKIE_NAME = "_maxwarden_session"
SESSION_COOKIE_EXPIRY_DAYS int = 100
SESSION_COOKIE_ENTROPY int = 33
IDENTITY_COOKIE_NAME string = "_maxwarden_identity"
IDENTITY_COOKIE_EXPIRY_DAYS int = 30
IDENTITY_TOKEN_EXPIRY_DAYS int = 30
IDENTITY_COOKIE_ENTROPY int = 33
IDENTITY_LOGIN_PATH string = "/auth/login"
IDENTITY_LOGOUT_PATH string = "/auth/logout"
IDENTITY_DEFAULT_PATH string = "/app"
IDENTITY_AUTH_REDIRECT bool = true
IDENTITY_AUTH_KEY string = "CORRECT_HORSE_BATTERY_STAPLE"
// This key is NOT used for the hashing of passwords, or secure session data over the wire.
// It is ONLY used for performing quick file and string hashes, where security is not a factor.
DATA_HASH_KEY string = "01234567890123456789012345678901"
PASSWORD_MIN_LENGTH int = 8
PASSWORD_REQUIRED_UPPERCASE int = 1
PASSWORD_REQUIRED_LOWERCASE int = 1
PASSWORD_REQUIRED_NUMBERS int = 1
PASSWORD_REQUIRED_SYMBOLS int = 0
MAX_LOGIN_ATTEMPTS int = 5
)
type configuration struct {
Domain string `env:"DOMAIN"`
Host string `env:"HOST"`

29
constants/constants.go Normal file
View File

@@ -0,0 +1,29 @@
package constants
const (
SESSION_COOKIE_NAME = "_maxwarden_session"
SESSION_COOKIE_EXPIRY_DAYS int = 100
SESSION_COOKIE_ENTROPY int = 33
IDENTITY_COOKIE_NAME string = "_maxwarden_identity"
IDENTITY_COOKIE_EXPIRY_DAYS int = 30
IDENTITY_TOKEN_EXPIRY_DAYS int = 30
IDENTITY_COOKIE_ENTROPY int = 33
IDENTITY_LOGIN_PATH string = "/auth/login"
IDENTITY_LOGOUT_PATH string = "/auth/logout"
IDENTITY_DEFAULT_PATH string = "/app"
IDENTITY_AUTH_REDIRECT bool = true
IDENTITY_AUTH_KEY string = "CORRECT_HORSE_BATTERY_STAPLE"
// This key is NOT used for the hashing of passwords, or secure session data over the wire.
// It is ONLY used for performing quick file and string hashes, where security is not a factor.
DATA_HASH_KEY string = "01234567890123456789012345678901"
PASSWORD_MIN_LENGTH int = 8
PASSWORD_REQUIRED_UPPERCASE int = 1
PASSWORD_REQUIRED_LOWERCASE int = 1
PASSWORD_REQUIRED_NUMBERS int = 1
PASSWORD_REQUIRED_SYMBOLS int = 0
MAX_LOGIN_ATTEMPTS int = 5
)

View File

@@ -44,7 +44,7 @@ func Filter(f EntryFilter) ([]Secret, error) {
user, _ := users.FetchById(f.UserId)
// we need to do the rest in memory because the data is encrypted, so we need to decrypt the data
secrets, decErr := security.DecryptDataWithKey[[]Secret](user.Data, f.MasterKey)
secrets, decErr := security.DecryptData[[]Secret](user.Data, f.MasterKey)
if decErr != nil {
return nil, decErr
}
@@ -83,7 +83,7 @@ func Filter(f EntryFilter) ([]Secret, error) {
func FetchSecretFromID(userId int32, masterKey string, secretId string) (Secret, error) {
user, _ := users.FetchById(userId)
secrets, decErr := security.DecryptDataWithKey[[]Secret](user.Data, masterKey)
secrets, decErr := security.DecryptData[[]Secret](user.Data, masterKey)
if decErr != nil {
return Secret{}, decErr
}
@@ -104,7 +104,7 @@ func FetchSecretFromID(userId int32, masterKey string, secretId string) (Secret,
func DeleteSecret(userId int32, masterKey string, secretId string) error {
user, _ := users.FetchById(userId)
secrets, decErr := security.DecryptDataWithKey[[]Secret](user.Data, masterKey)
secrets, decErr := security.DecryptData[[]Secret](user.Data, masterKey)
if decErr != nil {
return decErr
}
@@ -121,7 +121,7 @@ func DeleteSecret(userId int32, masterKey string, secretId string) error {
}
}
enc, _ := security.EncryptDataWithKey(&output, masterKey)
enc, _ := security.EncryptData(&output, masterKey)
user.Data = enc
_, userErr := users.Update(user)
@@ -132,7 +132,7 @@ func DeleteSecret(userId int32, masterKey string, secretId string) error {
func Update(userId int32, masterKey string, secret Secret) error {
user, _ := users.FetchById(userId)
secrets, _ := security.DecryptDataWithKey[[]Secret](user.Data, masterKey)
secrets, _ := security.DecryptData[[]Secret](user.Data, masterKey)
if secrets == nil {
return errors.New("user secrets are null")
}
@@ -149,7 +149,7 @@ func Update(userId int32, masterKey string, secret Secret) error {
}
}
enc, _ := security.EncryptDataWithKey(secrets, masterKey)
enc, _ := security.EncryptData(secrets, masterKey)
user.Data = enc
_, updateErr := users.Update(user)
@@ -160,7 +160,7 @@ func Update(userId int32, masterKey string, secret Secret) error {
func Add(userId int32, masterKey string, secret Secret) error {
user, _ := users.FetchById(userId)
secrets, _ := security.DecryptDataWithKey[[]Secret](user.Data, masterKey)
secrets, _ := security.DecryptData[[]Secret](user.Data, masterKey)
if secrets == nil {
return errors.New("user secrets are null")
}
@@ -171,7 +171,7 @@ func Add(userId int32, masterKey string, secret Secret) error {
*secrets = append(*secrets, secret)
enc, _ := security.EncryptDataWithKey(secrets, masterKey)
enc, _ := security.EncryptData(secrets, masterKey)
user.Data = enc
_, updateErr := users.Update(user)

View File

@@ -7,7 +7,7 @@ import (
. "maragu.dev/gomponents/html"
"maxwarden/auth"
"maxwarden/config"
"maxwarden/constants"
"maxwarden/middleware"
"log"
@@ -46,7 +46,7 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
return
}
defaultPath := config.IDENTITY_DEFAULT_PATH
defaultPath := constants.IDENTITY_DEFAULT_PATH
http.Redirect(w, r, defaultPath, http.StatusFound)
}
}

View File

@@ -2,7 +2,7 @@ package auth
import (
"net/http"
"maxwarden/config"
"maxwarden/constants"
"maxwarden/middleware"
)
@@ -10,5 +10,5 @@ func LogoutHandler(w http.ResponseWriter, r *http.Request) {
middleware.DeleteIdentityCookie(w, r)
middleware.DeleteSessionCookie(w, r)
http.Redirect(w, r, config.IDENTITY_LOGIN_PATH, http.StatusFound)
http.Redirect(w, r, constants.IDENTITY_LOGIN_PATH, http.StatusFound)
}

View File

@@ -3,12 +3,13 @@ package middleware
import (
"context"
"log"
"net/http"
"net/url"
"maxwarden/auth"
"maxwarden/config"
"maxwarden/constants"
"maxwarden/security"
"maxwarden/users"
"net/http"
"net/url"
"strings"
"time"
)
@@ -16,10 +17,10 @@ import (
type identityKey struct{}
func LoadIdentity(h http.HandlerFunc, requireAuth bool) http.HandlerFunc {
loginPath := config.IDENTITY_LOGIN_PATH
logoutPath := config.IDENTITY_LOGOUT_PATH
defaultPath := config.IDENTITY_DEFAULT_PATH
redirect := config.IDENTITY_AUTH_REDIRECT
loginPath := constants.IDENTITY_LOGIN_PATH
logoutPath := constants.IDENTITY_LOGOUT_PATH
defaultPath := constants.IDENTITY_DEFAULT_PATH
redirect := constants.IDENTITY_AUTH_REDIRECT
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var identity *auth.Identity
@@ -35,7 +36,10 @@ func LoadIdentity(h http.HandlerFunc, requireAuth bool) http.HandlerFunc {
if len(splitToken) >= 2 {
token = splitToken[1]
identity, _ = security.DecryptData[auth.Identity]([]byte(security.DecodeBase58(token)))
identity, _ = security.DecryptData[auth.Identity](
[]byte(security.DecodeBase58(token)),
config.GetConfig().IdentityPrivateKey,
)
}
if identity == nil {
@@ -51,9 +55,12 @@ func LoadIdentity(h http.HandlerFunc, requireAuth bool) http.HandlerFunc {
return
}
} else {
identityCookie, err := r.Cookie(config.IDENTITY_COOKIE_NAME)
identityCookie, err := r.Cookie(constants.IDENTITY_COOKIE_NAME)
if err == nil {
identity, _ = security.DecryptData[auth.Identity]([]byte(security.DecodeBase58(identityCookie.Value)))
identity, _ = security.DecryptData[auth.Identity](
[]byte(security.DecodeBase58(identityCookie.Value)),
config.GetConfig().IdentityPrivateKey,
)
}
if identity == nil {
@@ -117,7 +124,7 @@ func PutIdentityCookie(w http.ResponseWriter, r *http.Request, identity *auth.Id
// calculate total bytes used by other cookies
var totalBytes int
for _, cookie := range cookies {
if cookie.Name == config.IDENTITY_COOKIE_NAME {
if cookie.Name == constants.IDENTITY_COOKIE_NAME {
continue
} else {
totalBytes += len(cookie.Value)
@@ -139,7 +146,7 @@ func PutIdentityCookie(w http.ResponseWriter, r *http.Request, identity *auth.Id
// The key should not be checked into VCS, and be regenerated if theft is
// suspected. Resetting the key will log *everyone* out, since no sessions
// or identities will validate.
identityData, err := security.EncryptData(identity)
identityData, err := security.EncryptData(identity, config.GetConfig().IdentityPrivateKey)
if err != nil {
return
}
@@ -152,7 +159,7 @@ func PutIdentityCookie(w http.ResponseWriter, r *http.Request, identity *auth.Id
}
httpCookie := &http.Cookie{
Name: config.IDENTITY_COOKIE_NAME,
Name: constants.IDENTITY_COOKIE_NAME,
Value: security.EncodeBase58(identityData),
HttpOnly: true,
Secure: r.URL.Scheme == "https",
@@ -167,7 +174,7 @@ func PutIdentityCookie(w http.ResponseWriter, r *http.Request, identity *auth.Id
func DeleteIdentityCookie(w http.ResponseWriter, r *http.Request) {
http.SetCookie(w, &http.Cookie{
Name: config.IDENTITY_COOKIE_NAME,
Name: constants.IDENTITY_COOKIE_NAME,
MaxAge: -1,
Expires: time.Now().Add(-100 * time.Hour),
Path: "/",

View File

@@ -3,9 +3,10 @@ package middleware
import (
"context"
"log"
"net/http"
"maxwarden/config"
"maxwarden/constants"
"maxwarden/security"
"net/http"
"time"
)
@@ -15,9 +16,13 @@ func LoadSession(h http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var sessionMap map[string]interface{}
sessionCookie, err := r.Cookie(config.SESSION_COOKIE_NAME)
sessionCookie, err := r.Cookie(constants.SESSION_COOKIE_NAME)
if err == nil {
decryptMap, _ := security.DecryptData[map[string]interface{}]([]byte(security.DecodeBase58(sessionCookie.Value)))
decryptMap, _ := security.DecryptData[map[string]interface{}](
[]byte(security.DecodeBase58(sessionCookie.Value)),
config.GetConfig().IdentityPrivateKey,
)
sessionMap = *decryptMap
}
@@ -41,14 +46,14 @@ func PutSessionCookie(w http.ResponseWriter, r *http.Request, session map[string
// calculate total bytes used by other cookies
var totalBytes int
for _, cookie := range cookies {
if cookie.Name == config.SESSION_COOKIE_NAME {
if cookie.Name == constants.SESSION_COOKIE_NAME {
continue
} else {
totalBytes += len(cookie.Value)
}
}
sessionData, err := security.EncryptData(&session)
sessionData, err := security.EncryptData(&session, config.GetConfig().IdentityPrivateKey)
if err != nil {
return
}
@@ -61,7 +66,7 @@ func PutSessionCookie(w http.ResponseWriter, r *http.Request, session map[string
}
httpCookie := &http.Cookie{
Name: config.SESSION_COOKIE_NAME,
Name: constants.SESSION_COOKIE_NAME,
Value: security.EncodeBase58(sessionData),
HttpOnly: true,
Secure: r.URL.Scheme == "https",
@@ -74,7 +79,7 @@ func PutSessionCookie(w http.ResponseWriter, r *http.Request, session map[string
func DeleteSessionCookie(w http.ResponseWriter, r *http.Request) {
http.SetCookie(w, &http.Cookie{
Name: config.SESSION_COOKIE_NAME,
Name: constants.SESSION_COOKIE_NAME,
MaxAge: -1,
Expires: time.Now().Add(-100 * time.Hour),
Path: "/",

View File

@@ -11,12 +11,12 @@ import (
"fmt"
"io"
"log"
"maxwarden/config"
"os"
"maxwarden/constants"
"github.com/btcsuite/btcutil/base58"
"github.com/minio/highwayhash"
"golang.org/x/crypto/bcrypt"
)
@@ -59,7 +59,7 @@ func SHA512_58(in string) string {
}
func HighwayHash58(in string) (string, error) {
key := []byte(config.DATA_HASH_KEY)
key := []byte(constants.DATA_HASH_KEY)
hasher, err := highwayhash.New(key)
if err != nil {
@@ -77,7 +77,7 @@ func HighwayHash58(in string) (string, error) {
}
func HighwayHash(in string) (string, error) {
key := []byte(config.DATA_HASH_KEY)
key := []byte(constants.DATA_HASH_KEY)
hasher, err := highwayhash.New(key)
if err != nil {
@@ -93,7 +93,7 @@ func HighwayHash(in string) (string, error) {
}
func QuickFileHash(filepath string) (string, error) {
key := []byte(config.DATA_HASH_KEY)
key := []byte(constants.DATA_HASH_KEY)
file, err := os.Open(filepath)
if err != nil {
@@ -196,17 +196,7 @@ func DecryptSecret(encryptedData []byte, passKey string) ([]byte, error) {
return decryptedData, nil
}
// Encrypt data using default private key
func EncryptData[T any](data *T) ([]byte, error) {
return EncryptDataWithKey(data, config.GetConfig().IdentityPrivateKey)
}
// Decrypt data using default private key
func DecryptData[T any](data []byte) (*T, error) {
return DecryptDataWithKey[T](data, config.GetConfig().IdentityPrivateKey)
}
func EncryptDataWithKey[T any](data *T, key string) ([]byte, error) {
func EncryptData[T any](data *T, key string) ([]byte, error) {
// serialize
b := bytes.Buffer{}
e := gob.NewEncoder(&b)
@@ -224,7 +214,7 @@ func EncryptDataWithKey[T any](data *T, key string) ([]byte, error) {
return out, nil
}
func DecryptDataWithKey[T any](data []byte, key string) (*T, error) {
func DecryptData[T any](data []byte, key string) (*T, error) {
dest := new(T)
secret, err := DecryptSecret(data, key)