package main import ( "encoding/json" "fmt" "igit.com/xbase/raft" ) // DemoAuthCmds extends the standard CLI with specific auth testing scenarios func RegisterDemoAuthCommands(cli *raft.CLI) { // 1. Scenario: Initialize Sales System cli.RegisterCommand("demo-init", "Setup roles and users for demo", func(parts []string, server *raft.KVServer) { // This must be run by root // Create Role: Sales Manager (0.5 - 0.9 discount) managerRole := raft.Role{ Name: "sales_manager", Permissions: []raft.Permission{ { KeyPattern: "product.discount", Actions: []string{"write", "read"}, Constraint: &raft.Constraint{Min: floatPtr(0.5), Max: floatPtr(0.9)}, }, { KeyPattern: "product.info.*", Actions: []string{"write", "read"}, }, }, } // Create Role: Junior Sales (0.8 - 0.95 discount) juniorRole := raft.Role{ Name: "junior_sales", Permissions: []raft.Permission{ { KeyPattern: "product.discount", Actions: []string{"write", "read"}, Constraint: &raft.Constraint{Min: floatPtr(0.8), Max: floatPtr(0.95)}, }, }, } // Save Roles role1JSON, _ := json.Marshal(managerRole) role2JSON, _ := json.Marshal(juniorRole) // We use SetAuthenticated with current token (should be root) // Or if auth not enabled yet, regular Set works. // Assuming we are logged in as root. // Use internal Set for demo setup convenience (bypassing CLI token check if we want, but better to follow rules) // Let's assume the user ran 'auth-init' and 'login root' before this. // We will try to use the token from CLI if available. fmt.Println("Creating roles...") // Direct Set for demo purposes if auth is not strictly enforced yet or we are root if err := server.Set("system.role.sales_manager", string(role1JSON)); err != nil { fmt.Printf("Error creating manager role: %v\n", err) } if err := server.Set("system.role.junior_sales", string(role2JSON)); err != nil { fmt.Printf("Error creating junior role: %v\n", err) } // Create Users fmt.Println("Creating users: 'alice' (Manager) and 'bob' (Junior)...") alice := raft.User{ Username: "alice", Salt: "salt1", PasswordHash: hashPassword("pass123", "salt1"), // Helper needed or manual hash Roles: []string{"sales_manager"}, } bob := raft.User{ Username: "bob", Salt: "salt2", PasswordHash: hashPassword("pass123", "salt2"), Roles: []string{"junior_sales"}, } user1JSON, _ := json.Marshal(alice) user2JSON, _ := json.Marshal(bob) server.Set("system.user.alice", string(user1JSON)) server.Set("system.user.bob", string(user2JSON)) fmt.Println("Demo environment initialized!") fmt.Println("Try: login alice pass123") fmt.Println("Then: set product.discount 0.6 (Should succeed)") fmt.Println("Then: set product.discount 0.1 (Should fail)") }) } // Helpers duplicated from auth.go for demo setup (since they are private there) // In a real app we would export them or use the API func hashPassword(password, salt string) string { return raft.HashPassword(password, salt) } func floatPtr(v float64) *float64 { return &v }