package main import ( "encoding/json" "flag" "fmt" "log" "math/rand" "net/http" "os" "stalwart_client/pkg/api" "strconv" "strings" "time" ) // 请求和响应结构 type CreateUserRequest struct { Email string `json:"email"` Password string `json:"password,omitempty"` Description string `json:"description,omitempty"` Quota int64 `json:"quota,omitempty"` } type UserResponse struct { ID int `json:"id"` Username string `json:"username"` Email string `json:"email"` Password string `json:"password,omitempty"` Success bool `json:"success"` Message string `json:"message,omitempty"` } type ListUsersRequest struct { Limit int `json:"limit,omitempty"` Page int `json:"page,omitempty"` } type ListUsersResponse struct { Users []api.User `json:"users"` Total int `json:"total"` Success bool `json:"success"` Message string `json:"message,omitempty"` } type GetUserRequest struct { ID int `json:"id,omitempty"` Email string `json:"email,omitempty"` } type GetUserResponse struct { User map[string]interface{} `json:"user"` Success bool `json:"success"` Message string `json:"message,omitempty"` } type GetEmailRequest struct { Email string `json:"email"` Password string `json:"password"` Server string `json:"server,omitempty"` Port int `json:"port,omitempty"` Count int `json:"count,omitempty"` } type EmailResponse struct { Emails []*api.EmailMessage `json:"emails"` Success bool `json:"success"` Message string `json:"message,omitempty"` } // 全局变量 var ( client *api.Client ) // API处理函数 // 创建用户 func createUserHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } var req CreateUserRequest // 尝试解析请求体,但即使失败也继续处理 _ = json.NewDecoder(r.Body).Decode(&req) // 如果email为空,自动生成一个随机用户名和域名 if req.Email == "" { randomUsername := api.GenerateRandomPassword(8) req.Email = fmt.Sprintf("%s@%s", randomUsername, client.Config.User.DefaultDomain) } // 如果密码为空,将由系统自动生成 // 如果配额为0,使用默认配额 if req.Quota == 0 { req.Quota = client.Config.User.DefaultQuota } // 如果描述为空,添加默认描述 if req.Description == "" { req.Description = "系统自动创建的用户" } // 创建用户 userID, username, email, password, err := client.CreateEmailUser( req.Email, req.Password, req.Description, req.Quota, api.APIKeyAuth, // 默认使用API Key认证 "", "", client.Config.Auth.APIKey, ) if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "success": "false", "message": fmt.Sprintf("创建用户失败: %v", err), }) return } // 返回响应 response := UserResponse{ ID: userID, Username: username, Email: email, Password: password, Success: true, Message: "用户创建成功", } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } // 创建简单用户 - 无需任何参数,直接返回创建的用户信息 func createSimpleUserHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet && r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } // 生成随机用户名 - 确保不包含特殊字符 randomUsername := api.GenerateRandomUsername(8) // 确保用户名只包含字母和数字 for i := 0; i < len(randomUsername); i++ { if !((randomUsername[i] >= 'a' && randomUsername[i] <= 'z') || (randomUsername[i] >= '0' && randomUsername[i] <= '9')) { // 替换为字母 randomUsername = randomUsername[:i] + "x" + randomUsername[i+1:] } } email := fmt.Sprintf("%s@%s", randomUsername, client.Config.User.DefaultDomain) description := "自动创建的临时用户" quota := client.Config.User.DefaultQuota // 创建用户 userID, username, email, password, err := client.CreateEmailUser( email, "", // 空密码,系统会自动生成 description, quota, api.APIKeyAuth, "", "", client.Config.Auth.APIKey, ) if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "success": "false", "message": fmt.Sprintf("创建用户失败: %v", err), }) return } // 返回简单格式的响应 response := map[string]interface{}{ "id": userID, "username": username, "email": email, "password": password, "server": fmt.Sprintf("mail.%s", strings.Split(email, "@")[1]), "success": true, } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } // 创建模拟用户 - 不实际调用API,只生成模拟数据 func createMockUserHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet && r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } // 生成随机用户名 - 确保不包含特殊字符 randomUsername := api.GenerateRandomUsername(8) // 确保用户名只包含字母和数字 for i := 0; i < len(randomUsername); i++ { if !((randomUsername[i] >= 'a' && randomUsername[i] <= 'z') || (randomUsername[i] >= '0' && randomUsername[i] <= '9')) { // 替换为字母 randomUsername = randomUsername[:i] + "x" + randomUsername[i+1:] } } domain := client.Config.User.DefaultDomain email := fmt.Sprintf("%s@%s", randomUsername, domain) password := api.GenerateRandomPassword(12) // 返回模拟响应 userID := rand.Intn(1000) + 1000 // 随机生成ID response := map[string]interface{}{ "id": userID, "username": randomUsername, "email": email, "password": password, "server": fmt.Sprintf("mail.%s", domain), "imap_server": fmt.Sprintf("mail.%s", domain), "imap_port": 993, "smtp_server": fmt.Sprintf("mail.%s", domain), "smtp_port": 465, "description": "模拟生成的测试用户", "quota": client.Config.User.DefaultQuota, "created_time": time.Now().Format(time.RFC3339), "success": true, "message": "模拟用户创建成功(仅本地数据,未实际调用API)", } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } // 列出用户 func listUsersHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { w.WriteHeader(http.StatusMethodNotAllowed) return } // 解析查询参数 limitStr := r.URL.Query().Get("limit") pageStr := r.URL.Query().Get("page") limit := 100 page := 1 if limitStr != "" { if l, err := strconv.Atoi(limitStr); err == nil && l > 0 { limit = l } } if pageStr != "" { if p, err := strconv.Atoi(pageStr); err == nil && p > 0 { page = p } } // 获取用户列表 userList, err := client.ListUsers( api.APIKeyAuth, // 默认使用API Key认证 "", "", client.Config.Auth.APIKey, limit, page, ) if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "success": "false", "message": fmt.Sprintf("获取用户列表失败: %v", err), }) return } // 返回响应 response := ListUsersResponse{ Users: userList.Data.Items, Total: userList.Data.Total, Success: true, Message: "获取用户列表成功", } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } // 获取单个用户信息 func getUserHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { w.WriteHeader(http.StatusMethodNotAllowed) return } // 解析参数 idStr := r.URL.Query().Get("id") email := r.URL.Query().Get("email") // 如果两个参数都为空,尝试从路径中获取 if idStr == "" && email == "" { pathParts := strings.Split(r.URL.Path, "/") if len(pathParts) > 3 { // 路径形式可能是 /api/get_user/123 或 /api/get_user/user@example.com lastPart := pathParts[len(pathParts)-1] if _, err := strconv.Atoi(lastPart); err == nil { // 是数字,当作ID处理 idStr = lastPart } else if strings.Contains(lastPart, "@") { // 包含@,当作邮箱处理 email = lastPart } } } if idStr == "" && email == "" { w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "success": "false", "message": "必须提供用户ID或邮箱地址", }) return } var userInfo map[string]interface{} var err error if idStr != "" { // 通过ID查询 id, err := strconv.Atoi(idStr) if err != nil { w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "success": "false", "message": "无效的用户ID", }) return } userInfo, err = client.GetUserDetails( id, api.APIKeyAuth, // 默认使用API Key认证 "", "", client.Config.Auth.APIKey, ) } else { // 通过邮箱查询 userInfo, err = client.GetUserByEmail( email, api.APIKeyAuth, // 默认使用API Key认证 "", "", client.Config.Auth.APIKey, ) } if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "success": "false", "message": fmt.Sprintf("获取用户信息失败: %v", err), }) return } // 返回响应 response := GetUserResponse{ User: userInfo, Success: true, Message: "获取用户信息成功", } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } // 获取邮件 func getEmailsHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } var req GetEmailRequest // 尝试解析请求体,但即使失败也继续处理 _ = json.NewDecoder(r.Body).Decode(&req) // 检查是否提供了邮箱和密码参数 if req.Email == "" || req.Password == "" { // 也可以从URL参数获取 req.Email = r.URL.Query().Get("email") req.Password = r.URL.Query().Get("password") // 如果仍然为空,则返回错误 if req.Email == "" || req.Password == "" { w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(map[string]string{ "success": "false", "message": "邮箱地址和密码必须提供", }) return } } // 设置默认参数 server := req.Server if server == "" { // 尝试从邮箱地址提取域名 parts := strings.Split(req.Email, "@") if len(parts) > 1 { server = fmt.Sprintf("mail.%s", parts[1]) } else { server = "mail.evnmail.com" } } port := req.Port if port == 0 { port = 993 } count := req.Count if count == 0 { count = 5 // 默认获取5封邮件 } // 获取邮件 emails, err := api.GetLatestEmails( req.Email, req.Password, server, port, true, // 使用SSL count, ) if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(map[string]string{ "success": "false", "message": fmt.Sprintf("获取邮件失败: %v", err), }) return } // 返回响应 response := EmailResponse{ Emails: emails, Success: true, Message: fmt.Sprintf("成功获取 %d 封邮件", len(emails)), } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) } // 启动Web服务器 func main() { // 初始化随机数生成器 rand.Seed(time.Now().UnixNano()) // 解析命令行参数 portPtr := flag.Int("p", 8080, "服务器端口") configPtr := flag.String("c", "", "配置文件路径") flag.Parse() // 加载配置 config, err := api.LoadConfig(*configPtr) if err != nil { fmt.Printf("加载配置失败: %v\n", err) os.Exit(1) } // 创建客户端 client = api.NewClient(config) // 设置路由 - 不再使用authMiddleware http.HandleFunc("/api/create_user", createUserHandler) http.HandleFunc("/api/simple_user", createSimpleUserHandler) http.HandleFunc("/api/mock_user", createMockUserHandler) http.HandleFunc("/api/list_users", listUsersHandler) http.HandleFunc("/api/get_user", getUserHandler) http.HandleFunc("/api/get_emails", getEmailsHandler) // 添加一个简单的健康检查端点 http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("OK")) }) // 添加一个简单的根路径处理 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } w.WriteHeader(http.StatusOK) w.Write([]byte("Stalwart 邮件 API 服务运行中")) }) // 启动服务器 port := *portPtr addr := fmt.Sprintf(":%d", port) fmt.Printf("启动Web服务器,监听端口: %d\n", port) fmt.Printf("API端点 (无需认证):\n") fmt.Printf(" - POST /api/create_user (创建用户,可自定义参数)\n") fmt.Printf(" - GET /api/simple_user (创建随机用户,无需任何参数)\n") fmt.Printf(" - GET /api/mock_user (创建模拟用户,仅本地数据)\n") fmt.Printf(" - GET /api/list_users (获取用户列表)\n") fmt.Printf(" - GET /api/get_user (获取用户信息)\n") fmt.Printf(" - POST /api/get_emails (获取用户邮件)\n") if err := http.ListenAndServe(addr, nil); err != nil { log.Fatalf("启动服务器失败: %v", err) } }