refactor: extract SHA3 hashing utilities to utils/hash.go

- Move all SHA3-512 hashing functions to utils package
- Update import statements and function calls
- Maintain zero functional changes
- First step in systematic main.go refactoring

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-18 18:36:47 +03:00
parent 7d7e6e412a
commit f9965c8f9c
4 changed files with 134 additions and 25 deletions

33
--help Normal file
View File

@@ -0,0 +1,33 @@
node_id: GALACTICA
bind_address: 127.0.0.1
port: 8080
data_dir: ./data
seed_nodes: []
read_only: false
log_level: info
gossip_interval_min: 60
gossip_interval_max: 120
sync_interval: 300
catchup_interval: 120
bootstrap_max_age_hours: 720
throttle_delay_ms: 100
fetch_delay_ms: 50
compression_enabled: true
compression_level: 3
default_ttl: "0"
max_json_size: 1048576
rate_limit_requests: 100
rate_limit_window: 1m
tamper_log_actions:
- data_write
- user_create
- auth_failure
backup_enabled: true
backup_schedule: 0 0 * * *
backup_path: ./backups
backup_retention: 7
auth_enabled: true
tamper_logging_enabled: true
clustering_enabled: true
rate_limiting_enabled: true
revision_history_enabled: true

33
main.go
View File

@@ -27,8 +27,9 @@ import (
"github.com/klauspost/compress/zstd" "github.com/klauspost/compress/zstd"
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"golang.org/x/crypto/sha3"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"kvs/utils"
) )
// Core data structures // Core data structures
@@ -329,24 +330,6 @@ type Server struct {
backupMu sync.RWMutex // Protects backup status backupMu sync.RWMutex // Protects backup status
} }
// SHA3-512 hashing utilities for Phase 2 authentication
func hashSHA3512(input string) string {
hasher := sha3.New512()
hasher.Write([]byte(input))
return hex.EncodeToString(hasher.Sum(nil))
}
func hashUserNickname(nickname string) string {
return hashSHA3512(nickname)
}
func hashGroupName(groupname string) string {
return hashSHA3512(groupname)
}
func hashToken(token string) string {
return hashSHA3512(token)
}
// Phase 2: Storage key generation utilities // Phase 2: Storage key generation utilities
func userStorageKey(userUUID string) string { func userStorageKey(userUUID string) string {
@@ -488,7 +471,7 @@ func validateJWT(tokenString string) (*JWTClaims, error) {
// storeAPIToken stores an API token in BadgerDB with TTL // storeAPIToken stores an API token in BadgerDB with TTL
func (s *Server) storeAPIToken(tokenString string, userUUID string, scopes []string, expiresAt int64) error { func (s *Server) storeAPIToken(tokenString string, userUUID string, scopes []string, expiresAt int64) error {
tokenHash := hashToken(tokenString) tokenHash := utils.HashToken(tokenString)
apiToken := APIToken{ apiToken := APIToken{
TokenHash: tokenHash, TokenHash: tokenHash,
@@ -598,7 +581,7 @@ func (s *Server) authenticateRequest(r *http.Request) (*AuthContext, error) {
} }
// Verify token exists in our database (not revoked) // Verify token exists in our database (not revoked)
tokenHash := hashToken(tokenString) tokenHash := utils.HashToken(tokenString)
_, err = s.getAPIToken(tokenHash) _, err = s.getAPIToken(tokenHash)
if err == badger.ErrKeyNotFound { if err == badger.ErrKeyNotFound {
return nil, fmt.Errorf("token not found or revoked") return nil, fmt.Errorf("token not found or revoked")
@@ -1152,7 +1135,7 @@ func getMerkleLogKey(timestamp string) string {
func generateLogSignature(timestamp, action, userUUID, resource string) string { func generateLogSignature(timestamp, action, userUUID, resource string) string {
// Concatenate all fields in a deterministic order // Concatenate all fields in a deterministic order
data := fmt.Sprintf("%s|%s|%s|%s", timestamp, action, userUUID, resource) data := fmt.Sprintf("%s|%s|%s|%s", timestamp, action, userUUID, resource)
return hashSHA3512(data) return utils.HashSHA3512(data)
} }
// isActionLogged checks if a specific action should be logged // isActionLogged checks if a specific action should be logged
@@ -2771,7 +2754,7 @@ func (s *Server) createUserHandler(w http.ResponseWriter, r *http.Request) {
user := User{ user := User{
UUID: userUUID, UUID: userUUID,
NicknameHash: hashUserNickname(req.Nickname), NicknameHash: utils.HashUserNickname(req.Nickname),
Groups: []string{}, Groups: []string{},
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,
@@ -2883,7 +2866,7 @@ func (s *Server) updateUserHandler(w http.ResponseWriter, r *http.Request) {
user.UpdatedAt = now user.UpdatedAt = now
if req.Nickname != "" { if req.Nickname != "" {
user.NicknameHash = hashUserNickname(req.Nickname) user.NicknameHash = utils.HashUserNickname(req.Nickname)
} }
if req.Groups != nil { if req.Groups != nil {
@@ -2971,7 +2954,7 @@ func (s *Server) createGroupHandler(w http.ResponseWriter, r *http.Request) {
group := Group{ group := Group{
UUID: groupUUID, UUID: groupUUID,
NameHash: hashGroupName(req.Groupname), NameHash: utils.HashGroupName(req.Groupname),
Members: req.Members, Members: req.Members,
CreatedAt: now, CreatedAt: now,
UpdatedAt: now, UpdatedAt: now,

68
refactor.md Normal file
View File

@@ -0,0 +1,68 @@
# Refactoring Proposal for KVS Main.go
After analyzing your 3,990-line main.go file, I've identified clear functional areas that can be separated into manageable modules.
Here's my comprehensive refactoring proposal:
Proposed File Structure
kvs/
├── main.go # Entry point + minimal server setup
├── config/
│ └── config.go # Configuration structures and loading
├── types/
│ └── types.go # All data structures and type definitions
├── auth/
│ ├── auth.go # Authentication & authorization logic
│ ├── jwt.go # JWT token management
│ ├── middleware.go # Auth middleware
│ └── permissions.go # Permission checking utilities
├── storage/
│ ├── storage.go # BadgerDB operations and utilities
│ ├── compression.go # ZSTD compression/decompression
│ ├── ttl.go # TTL and metadata management
│ └── revision.go # Revision history system
├── cluster/
│ ├── gossip.go # Gossip protocol implementation
│ ├── members.go # Member management
│ ├── sync.go # Data synchronization
│ └── merkle.go # Merkle tree operations
├── server/
│ ├── server.go # Server struct and core methods
│ ├── handlers.go # HTTP request handlers
│ ├── routes.go # Route setup
│ └── lifecycle.go # Server startup/shutdown logic
├── features/
│ ├── ratelimit.go # Rate limiting middleware and utilities
│ ├── tamperlog.go # Tamper-evident logging
│ └── backup.go # Backup system
└── utils/
└── hash.go # Hashing utilities (SHA3, etc.)
Key Benefits
1. Clear Separation of Concerns: Each package handles a specific responsibility
2. Better Testability: Smaller, focused functions are easier to unit test
3. Improved Maintainability: Changes to one feature don't affect others
4. Go Best Practices: Follows standard Go project layout conventions
5. Reduced Coupling: Clear interfaces between components
Functional Areas Identified
1. Configuration (~100 lines): Config structs, defaults, loading
2. Types (~400 lines): All data structures and constants
3. Authentication (~800 lines): User/Group/Token management, JWT, middleware
4. Storage (~600 lines): BadgerDB operations, compression, TTL, revisions
5. Clustering (~1,200 lines): Gossip, members, sync, Merkle trees
6. Server (~600 lines): Server struct, handlers, routes, lifecycle
7. Features (~200 lines): Rate limiting, tamper logging, backup
8. Utilities (~90 lines): Hashing and other utilities
Migration Strategy
1. Start with the most independent modules (types, config, utils)
2. Move storage and authentication components
3. Extract clustering logic
4. Refactor server components last
5. Create commits for each major module migration
The refactoring will maintain zero functional changes - purely cosmetic restructuring for better code organization.

25
utils/hash.go Normal file
View File

@@ -0,0 +1,25 @@
package utils
import (
"encoding/hex"
"golang.org/x/crypto/sha3"
)
// SHA3-512 hashing utilities for Phase 2 authentication
func HashSHA3512(input string) string {
hasher := sha3.New512()
hasher.Write([]byte(input))
return hex.EncodeToString(hasher.Sum(nil))
}
func HashUserNickname(nickname string) string {
return HashSHA3512(nickname)
}
func HashGroupName(groupname string) string {
return HashSHA3512(groupname)
}
func HashToken(token string) string {
return HashSHA3512(token)
}