Преглед на файлове

user init加固,增加其他root权限用户

robert преди 1 седмица
родител
ревизия
ba5a801a3e
променени са 5 файла, в които са добавени 72 реда и са изтрити 53 реда
  1. 13 3
      README.md
  2. 0 4
      auth.go
  3. 2 2
      cli.go
  4. 43 26
      server.go
  5. 14 18
      tcp_server.go

+ 13 - 3
README.md

@@ -160,11 +160,11 @@ err := server1.Join("node3", "127.0.0.1:9003")
     *   `search <pattern> [limit] [offset]`:搜索 Key(严格过滤权限,Superuser 可直接下推 DB)。
     *   `count <pattern>`:统计符合模式的 Key 数量(仅统计有权访问的 Key)。
 *   **权限管理**:
-    *   `auth-init <root_pass>`:初始化权限系统(Root Only)。
+    *   `auth-init <root_pass>`:初始化权限系统(仅能执行一次)。
     *   `login <user> <pass> [code]`:登录系统(全局会话)。
     *   `logout`:登出当前会话(全局注销)。
     *   `whoami`:查看当前登录用户及 Token 信息。
-*   **集群管理** (Root Only):
+*   **集群管理** (Admin Only):
     *   `join <id> <addr>`:将新节点加入集群。
     *   `leave <id>`:将节点移出集群。
 *   **系统监控**:
@@ -199,7 +199,7 @@ err := server1.Join("node3", "127.0.0.1:9003")
 2.  **Actions (操作)**: 允许的操作列表
     -   `read`: 读操作 (Get, Search, Count)。
     -   `write`: 写操作 (Set, Del)。
-    -   `admin`: 管理操作。
+    -   `admin`: 管理操作(User/Role 管理、Cluster Join/Leave)
     -   `*`: 所有操作。
 3.  **Constraint (数值约束)**: 针对 `write` 操作的细粒度控制
     -   **Min/Max**: 当 Value 为数值时,必须在指定范围内才允许写入(如折扣率限制在 0.5 ~ 0.9)。
@@ -209,6 +209,16 @@ err := server1.Join("node3", "127.0.0.1:9003")
 1.  **Deny 优先**: 检查用户 `DenyPermissions`,命中即拒绝。
 2.  **Effective Allow 检查**: 直接检查预计算好的 `EffectivePermissions` 列表,该列表已包含用户自身及所有继承角色的权限。
 
+**管理员权限 (Admin Capability)**:
+系统不再依赖硬编码的 `root` 用户名来判定管理员权限。任何拥有对全局资源 `*` 的 `admin` 操作权限的用户都被视为管理员。
+这意味着你可以创建多个具有不同名称的管理员账号(如 `admin`, `ops`),只需赋予其以下权限:
+```json
+{
+    "key": "*",
+    "actions": ["admin"]
+}
+```
+
 **性能优化 (High Performance)**:
 -   **预计算模型**: 当用户或角色变更时,系统自动重构受影响用户的 `EffectivePermissions`,将复杂的 RBAC 树扁平化。鉴权时仅需简单的列表遍历,无需递归查询。
 -   **本地 Session**: Session 验证纯内存操作,无网络 IO。

+ 0 - 4
auth.go

@@ -580,10 +580,6 @@ func (am *AuthManager) Logout(token string) error {
 func (am *AuthManager) GetSession(token string) (*Session, error) {
 	am.mu.RLock()
 	defer am.mu.RUnlock()
-	
-	if token == "SYSTEM_INTERNAL" {
-		return &Session{Username: "system"}, nil
-	}
 
 	session, ok := am.sessions[token]
 	if !ok {

+ 2 - 2
cli.go

@@ -357,8 +357,8 @@ func (c *CLI) registerDefaultCommands() {
 
 		switch subCmd {
 		case "init": // Was auth-init
-			if server.AuthManager.IsEnabled() && !server.IsRoot(token) {
-				printBoxed(fmt.Sprintf("%sPermission Denied: Auth already enabled. Login as root to re-init.%s", ColorRed, ColorReset))
+			if server.AuthManager.IsEnabled() {
+				printBoxed(fmt.Sprintf("%sPermission Denied: Auth system is already initialized.%s\nUse 'login' to access the system or contact administrator.", ColorRed, ColorReset))
 				return
 			}
 			fmt.Print("Enter root password: ")

+ 43 - 26
server.go

@@ -425,7 +425,23 @@ func (s *KVServer) GetSessionInfo(token string) (*Session, error) {
 	return s.AuthManager.GetSession(token)
 }
 
+// IsAdmin checks if the token belongs to a user with admin privileges
+// defined as having "admin" action on "*" key pattern
+func (s *KVServer) IsAdmin(token string) bool {
+	if !s.AuthManager.IsEnabled() {
+		return true // If auth disabled, everyone is admin (or handled by caller)
+	}
+	
+	// Check internal system token
+	if token == "SYSTEM_INTERNAL" {
+		return true
+	}
+
+	return s.AuthManager.CheckPermission(token, "*", ActionAdmin, "") == nil
+}
+
 // IsRoot checks if the token belongs to the root user
+// Deprecated: Use IsAdmin instead
 func (s *KVServer) IsRoot(token string) bool {
 	sess, err := s.AuthManager.GetSession(token)
 	if err != nil {
@@ -434,19 +450,19 @@ func (s *KVServer) IsRoot(token string) bool {
 	return sess.Username == "root"
 }
 
-// CreateUser creates a new user (Root only)
+// CreateUser creates a new user (Admin only)
 func (s *KVServer) CreateUser(username, password string, roles []string, token string) error {
-	if s.AuthManager.IsEnabled() && !s.IsRoot(token) {
-		return fmt.Errorf("permission denied: root access required")
+	if s.AuthManager.IsEnabled() && !s.IsAdmin(token) {
+		return fmt.Errorf("permission denied: admin access required")
 	}
 	// Use RegisterUserSync
 	return s.AuthManager.RegisterUser(username, password, roles)
 }
 
-// DeleteUser deletes a user (Root only)
+// DeleteUser deletes a user (Admin only)
 func (s *KVServer) DeleteUser(username string, token string) error {
-	if s.AuthManager.IsEnabled() && !s.IsRoot(token) {
-		return fmt.Errorf("permission denied: root access required")
+	if s.AuthManager.IsEnabled() && !s.IsAdmin(token) {
+		return fmt.Errorf("permission denied: admin access required")
 	}
 	// Check if user exists
 	if _, err := s.AuthManager.GetUser(username); err != nil {
@@ -459,10 +475,10 @@ func (s *KVServer) DeleteUser(username string, token string) error {
 	return s.DelSync(AuthUserPrefix + username)
 }
 
-// UpdateUser updates generic user fields (Root only)
+// UpdateUser updates generic user fields (Admin only)
 func (s *KVServer) UpdateUser(user User, token string) error {
-	if s.AuthManager.IsEnabled() && !s.IsRoot(token) {
-		return fmt.Errorf("permission denied: root access required")
+	if s.AuthManager.IsEnabled() && !s.IsAdmin(token) {
+		return fmt.Errorf("permission denied: admin access required")
 	}
 	// Check if user exists
 	if _, err := s.AuthManager.GetUser(user.Username); err != nil {
@@ -471,14 +487,15 @@ func (s *KVServer) UpdateUser(user User, token string) error {
 	return s.AuthManager.UpdateUser(user)
 }
 
-// ChangeUserPassword changes a user's password (Root or Self)
+// ChangeUserPassword changes a user's password (Admin or Self)
 func (s *KVServer) ChangeUserPassword(username, newPassword string, token string) error {
 	if s.AuthManager.IsEnabled() {
 		session, err := s.AuthManager.GetSession(token)
 		if err != nil {
 			return err
 		}
-		if session.Username != "root" && session.Username != username {
+		// Allow if Admin OR Self
+		if !s.IsAdmin(token) && session.Username != username {
 			return fmt.Errorf("permission denied")
 		}
 	}
@@ -488,42 +505,42 @@ func (s *KVServer) ChangeUserPassword(username, newPassword string, token string
 
 // Role Management Helpers
 
-// CreateRole creates a new role (Root only)
+// CreateRole creates a new role (Admin only)
 func (s *KVServer) CreateRole(name string, token string) error {
-	if s.AuthManager.IsEnabled() && !s.IsRoot(token) {
-		return fmt.Errorf("permission denied: root access required")
+	if s.AuthManager.IsEnabled() && !s.IsAdmin(token) {
+		return fmt.Errorf("permission denied: admin access required")
 	}
 	return s.AuthManager.CreateRole(name)
 }
 
-// DeleteRole deletes a role (Root only)
+// DeleteRole deletes a role (Admin only)
 func (s *KVServer) DeleteRole(name string, token string) error {
-	if s.AuthManager.IsEnabled() && !s.IsRoot(token) {
-		return fmt.Errorf("permission denied: root access required")
+	if s.AuthManager.IsEnabled() && !s.IsAdmin(token) {
+		return fmt.Errorf("permission denied: admin access required")
 	}
 	return s.AuthManager.DeleteRole(name)
 }
 
-// UpdateRole updates a role (Root only)
+// UpdateRole updates a role (Admin only)
 func (s *KVServer) UpdateRole(role Role, token string) error {
-	if s.AuthManager.IsEnabled() && !s.IsRoot(token) {
-		return fmt.Errorf("permission denied: root access required")
+	if s.AuthManager.IsEnabled() && !s.IsAdmin(token) {
+		return fmt.Errorf("permission denied: admin access required")
 	}
 	return s.AuthManager.UpdateRole(role)
 }
 
-// ListUsers lists all users (Root only)
+// ListUsers lists all users (Admin only)
 func (s *KVServer) ListUsers(token string) ([]*User, error) {
-	if s.AuthManager.IsEnabled() && !s.IsRoot(token) {
-		return nil, fmt.Errorf("permission denied: root access required")
+	if s.AuthManager.IsEnabled() && !s.IsAdmin(token) {
+		return nil, fmt.Errorf("permission denied: admin access required")
 	}
 	return s.AuthManager.ListUsers(), nil
 }
 
-// ListRoles lists all roles (Root only)
+// ListRoles lists all roles (Admin only)
 func (s *KVServer) ListRoles(token string) ([]*Role, error) {
-	if s.AuthManager.IsEnabled() && !s.IsRoot(token) {
-		return nil, fmt.Errorf("permission denied: root access required")
+	if s.AuthManager.IsEnabled() && !s.IsAdmin(token) {
+		return nil, fmt.Errorf("permission denied: admin access required")
 	}
 	return s.AuthManager.ListRoles(), nil
 }

+ 14 - 18
tcp_server.go

@@ -332,15 +332,10 @@ func (s *KVServer) executeCommand(session *TCPClientSession, line string) string
 		resp = "OK " + helpText
 
 	case "INFO":
-		// Check permission (Root only if auth enabled)
+		// Check permission (Admin only if auth enabled)
 		if s.AuthManager.IsEnabled() {
-			sess, err := s.AuthManager.GetSession(session.token)
-			if err != nil {
-				resp = fmt.Sprintf("ERR %v", err)
-				break
-			}
-			if sess.Username != "root" {
-				resp = "ERR Permission Denied: Root access required"
+			if !s.IsAdmin(session.token) {
+				resp = "ERR Permission Denied: Admin access required"
 				break
 			}
 		}
@@ -432,9 +427,8 @@ func (s *KVServer) executeCommand(session *TCPClientSession, line string) string
 		// Usage: JOIN <id> <addr>
 		// Admin only
 		if s.AuthManager.IsEnabled() {
-			sess, err := s.AuthManager.GetSession(session.token)
-			if err != nil || sess.Username != "root" {
-				resp = "ERR Permission Denied: Root access required"
+			if !s.IsAdmin(session.token) {
+				resp = "ERR Permission Denied: Admin access required"
 				break
 			}
 		}
@@ -453,9 +447,8 @@ func (s *KVServer) executeCommand(session *TCPClientSession, line string) string
 		// Usage: LEAVE <id>
 		// Admin only
 		if s.AuthManager.IsEnabled() {
-			sess, err := s.AuthManager.GetSession(session.token)
-			if err != nil || sess.Username != "root" {
-				resp = "ERR Permission Denied: Root access required"
+			if !s.IsAdmin(session.token) {
+				resp = "ERR Permission Denied: Admin access required"
 				break
 			}
 		}
@@ -617,14 +610,17 @@ func (s *KVServer) executeCommand(session *TCPClientSession, line string) string
 	
 	case "USER_UNLOCK":
 		// Usage: USER_UNLOCK <username>
+		if s.AuthManager.IsEnabled() {
+			if !s.IsAdmin(session.token) {
+				resp = "ERR Permission Denied: Admin access required"
+				break
+			}
+		}
+
 		if len(parts) < 2 {
 			resp = "ERR usage: USER_UNLOCK <username>"
 		} else {
 			// Manually clear the lock key
-			// Note: accessing server.Set directly bypasses auth check which is fine here 
-			// as the TCP session itself should be authenticated as admin ideally.
-			// For now we trust the connected client has rights or we check session.
-			// In real impl, check if session.username is root or has admin perm.
 			userToUnlock := parts[1]
 			// We use Del to remove the lock key
 			err := s.Del("system.lock." + userToUnlock)