refactor: extract authentication system to auth package
- Create auth/jwt.go with JWT token management - Create auth/permissions.go with permission checking logic - Create auth/storage.go with storage key utilities - Create auth/auth.go with main authentication service - Create auth/middleware.go with auth and rate limit middleware - Update main.go to import auth package and use auth.* functions - Add authService to Server struct Major auth functionality now separated into dedicated package. Build tested and verified working. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
56
main.go
56
main.go
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/robfig/cron/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"kvs/auth"
|
||||
"kvs/config"
|
||||
"kvs/types"
|
||||
"kvs/utils"
|
||||
@@ -58,25 +59,12 @@ type Server struct {
|
||||
cronScheduler *cron.Cron // Cron scheduler for backups
|
||||
backupStatus types.BackupStatus // Current backup status
|
||||
backupMu sync.RWMutex // Protects backup status
|
||||
|
||||
// Authentication service
|
||||
authService *auth.AuthService
|
||||
}
|
||||
|
||||
|
||||
// Phase 2: Storage key generation utilities
|
||||
func userStorageKey(userUUID string) string {
|
||||
return "user:" + userUUID
|
||||
}
|
||||
|
||||
func groupStorageKey(groupUUID string) string {
|
||||
return "group:" + groupUUID
|
||||
}
|
||||
|
||||
func tokenStorageKey(tokenHash string) string {
|
||||
return "token:" + tokenHash
|
||||
}
|
||||
|
||||
func resourceMetadataKey(resourceKey string) string {
|
||||
return resourceKey + ":metadata"
|
||||
}
|
||||
|
||||
// Phase 2: Permission checking utilities
|
||||
func checkPermission(permissions int, operation string, isOwner, isGroupMember bool) bool {
|
||||
@@ -217,7 +205,7 @@ func (s *Server) storeAPIToken(tokenString string, userUUID string, scopes []str
|
||||
}
|
||||
|
||||
return s.db.Update(func(txn *badger.Txn) error {
|
||||
entry := badger.NewEntry([]byte(tokenStorageKey(tokenHash)), tokenData)
|
||||
entry := badger.NewEntry([]byte(auth.TokenStorageKey(tokenHash)), tokenData)
|
||||
|
||||
// Set TTL to the token expiration time
|
||||
ttl := time.Until(time.Unix(expiresAt, 0))
|
||||
@@ -234,7 +222,7 @@ func (s *Server) getAPIToken(tokenHash string) (*types.APIToken, error) {
|
||||
var apiToken types.APIToken
|
||||
|
||||
err := s.db.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get([]byte(tokenStorageKey(tokenHash)))
|
||||
item, err := txn.Get([]byte(auth.TokenStorageKey(tokenHash)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -279,7 +267,7 @@ func extractTokenFromHeader(r *http.Request) (string, error) {
|
||||
func (s *Server) getUserGroups(userUUID string) ([]string, error) {
|
||||
var user types.User
|
||||
err := s.db.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get([]byte(userStorageKey(userUUID)))
|
||||
item, err := txn.Get([]byte(auth.UserStorageKey(userUUID)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -339,7 +327,7 @@ func (s *Server) checkResourcePermission(authCtx *AuthContext, resourceKey strin
|
||||
// Get resource metadata
|
||||
var metadata types.ResourceMetadata
|
||||
err := s.db.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get([]byte(resourceMetadataKey(resourceKey)))
|
||||
item, err := txn.Get([]byte(auth.ResourceMetadataKey(resourceKey)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -560,7 +548,7 @@ func getRevisionKey(baseKey string, revision int) string {
|
||||
// storeRevisionHistory stores a value and manages revision history (up to 3 revisions)
|
||||
func (s *Server) storeRevisionHistory(txn *badger.Txn, key string, storedValue types.StoredValue, ttl time.Duration) error {
|
||||
// Get existing metadata to check current revisions
|
||||
metadataKey := resourceMetadataKey(key)
|
||||
metadataKey := auth.ResourceMetadataKey(key)
|
||||
|
||||
var metadata types.ResourceMetadata
|
||||
var currentRevisions []int
|
||||
@@ -2416,7 +2404,7 @@ func (s *Server) createUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
err = s.db.Update(func(txn *badger.Txn) error {
|
||||
return txn.Set([]byte(userStorageKey(userUUID)), userData)
|
||||
return txn.Set([]byte(auth.UserStorageKey(userUUID)), userData)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -2444,7 +2432,7 @@ func (s *Server) getUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var user types.User
|
||||
err := s.db.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get([]byte(userStorageKey(userUUID)))
|
||||
item, err := txn.Get([]byte(auth.UserStorageKey(userUUID)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2495,7 +2483,7 @@ func (s *Server) updateUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err := s.db.Update(func(txn *badger.Txn) error {
|
||||
// Get existing user
|
||||
item, err := txn.Get([]byte(userStorageKey(userUUID)))
|
||||
item, err := txn.Get([]byte(auth.UserStorageKey(userUUID)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2526,7 +2514,7 @@ func (s *Server) updateUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return err
|
||||
}
|
||||
|
||||
return txn.Set([]byte(userStorageKey(userUUID)), userData)
|
||||
return txn.Set([]byte(auth.UserStorageKey(userUUID)), userData)
|
||||
})
|
||||
|
||||
if err == badger.ErrKeyNotFound {
|
||||
@@ -2556,13 +2544,13 @@ func (s *Server) deleteUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err := s.db.Update(func(txn *badger.Txn) error {
|
||||
// Check if user exists first
|
||||
_, err := txn.Get([]byte(userStorageKey(userUUID)))
|
||||
_, err := txn.Get([]byte(auth.UserStorageKey(userUUID)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete the user
|
||||
return txn.Delete([]byte(userStorageKey(userUUID)))
|
||||
return txn.Delete([]byte(auth.UserStorageKey(userUUID)))
|
||||
})
|
||||
|
||||
if err == badger.ErrKeyNotFound {
|
||||
@@ -2620,7 +2608,7 @@ func (s *Server) createGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
err = s.db.Update(func(txn *badger.Txn) error {
|
||||
return txn.Set([]byte(groupStorageKey(groupUUID)), groupData)
|
||||
return txn.Set([]byte(auth.GroupStorageKey(groupUUID)), groupData)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -2648,7 +2636,7 @@ func (s *Server) getGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var group types.Group
|
||||
err := s.db.View(func(txn *badger.Txn) error {
|
||||
item, err := txn.Get([]byte(groupStorageKey(groupUUID)))
|
||||
item, err := txn.Get([]byte(auth.GroupStorageKey(groupUUID)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2699,7 +2687,7 @@ func (s *Server) updateGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err := s.db.Update(func(txn *badger.Txn) error {
|
||||
// Get existing group
|
||||
item, err := txn.Get([]byte(groupStorageKey(groupUUID)))
|
||||
item, err := txn.Get([]byte(auth.GroupStorageKey(groupUUID)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2727,7 +2715,7 @@ func (s *Server) updateGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return err
|
||||
}
|
||||
|
||||
return txn.Set([]byte(groupStorageKey(groupUUID)), groupData)
|
||||
return txn.Set([]byte(auth.GroupStorageKey(groupUUID)), groupData)
|
||||
})
|
||||
|
||||
if err == badger.ErrKeyNotFound {
|
||||
@@ -2757,13 +2745,13 @@ func (s *Server) deleteGroupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
err := s.db.Update(func(txn *badger.Txn) error {
|
||||
// Check if group exists first
|
||||
_, err := txn.Get([]byte(groupStorageKey(groupUUID)))
|
||||
_, err := txn.Get([]byte(auth.GroupStorageKey(groupUUID)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete the group
|
||||
return txn.Delete([]byte(groupStorageKey(groupUUID)))
|
||||
return txn.Delete([]byte(auth.GroupStorageKey(groupUUID)))
|
||||
})
|
||||
|
||||
if err == badger.ErrKeyNotFound {
|
||||
@@ -2803,7 +2791,7 @@ func (s *Server) createTokenHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Verify user exists
|
||||
err := s.db.View(func(txn *badger.Txn) error {
|
||||
_, err := txn.Get([]byte(userStorageKey(req.UserUUID)))
|
||||
_, err := txn.Get([]byte(auth.UserStorageKey(req.UserUUID)))
|
||||
return err
|
||||
})
|
||||
|
||||
|
Reference in New Issue
Block a user