package main import ( "encoding/json" "fmt" "io" "net/http" "strconv" "super-frpc/postLog" "time" ) type Response struct { Success bool `json:"success"` Message string `json:"message,omitempty"` Data interface{} `json:"data,omitempty"` } func SendErrorResponse(w http.ResponseWriter, statusCode int, message string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(statusCode) resp := Response{ Success: false, Message: message, } jsonResp, err := json.Marshal(resp) if err != nil { postLog.Error(fmt.Sprintf("Failed to marshal error response: %v", err)) return } w.Write(jsonResp) } func SendSuccessResponse(w http.ResponseWriter, message string, data interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) resp := Response{ Success: true, Message: message, Data: data, } jsonResp, err := json.Marshal(resp) if err != nil { postLog.Error(fmt.Sprintf("Failed to marshal success response: %v", err)) return } w.Write(jsonResp) } func ValidateRequest(w http.ResponseWriter, r *http.Request, requiredFields ...string) (int, string, error) { // ValidateRequest validates the request body and header body, err := io.ReadAll(r.Body) if err != nil { return 0, "", fmt.Errorf("Failed to read request body: %w", err) } defer r.Body.Close() return ValidateRequestWithBody(w, r, body, requiredFields...) } func ValidateRequestWithBody(w http.ResponseWriter, r *http.Request, body []byte, requiredFields ...string) (int, string, error) { var reqMap map[string]interface{} if err := json.Unmarshal(body, &reqMap); err != nil { return 0, "", fmt.Errorf("Invalid request format: %w", err) } token := r.Header.Get("X-Token") if token == "" { return 0, "", fmt.Errorf("Token is required in header: %s", token) } if !isDebug { if !ValidateTimeStamp(r.Header) { return 0, "", fmt.Errorf("Invalid or missing X-Timestamp in header") } } userID, err := extractUserIDFromToken(token) if err != nil { return 0, "", fmt.Errorf("Invalid token format: %w", err) } if err := ValidateToken(userID, token); err != nil { return 0, "", fmt.Errorf("Token validation failed: %w", err) } for _, field := range requiredFields { if _, ok := reqMap[field]; !ok { return 0, "", fmt.Errorf("required field %s is missing: %s", field, reqMap[field]) } } return userID, token, nil } func ValidateRequestWithHeader(w http.ResponseWriter, r *http.Request, requiredFields ...string) (int, string, error) { token := r.Header.Get("X-Token") if token == "" { return 0, "", fmt.Errorf("Token is required in header: %s", token) } if !isDebug { if !ValidateTimeStamp(r.Header) { return 0, "", fmt.Errorf("Invalid or missing X-Timestamp in header") } } userID, err := extractUserIDFromToken(token) if err != nil { return 0, "", fmt.Errorf("Invalid token format in header: %w", err) } if err := ValidateToken(userID, token); err != nil { return 0, "", fmt.Errorf("Token validation failed in header: %w", err) } for _, field := range requiredFields { headerValue := r.Header.Get(fmt.Sprintf("X-%s", field)) if headerValue == "" { return 0, "", fmt.Errorf("required field %s is missing in header: %s", field, headerValue) } } return userID, token, nil } func GetUserType(userID int) (string, error) { user, err := GetUserByID(userID) if err != nil { return "", fmt.Errorf("Failed to get user type: %w", err) } return user.Type, nil } func CheckPermission(userID int, requiredTypes ...string) error { userType, err := GetUserType(userID) if err != nil { return fmt.Errorf("Failed to check permission: %w", err) } for _, t := range requiredTypes { if userType == t { return nil } } return fmt.Errorf("Permission denied for user type %s", userType) } func GetClientIP(r *http.Request) string { forwarded := r.Header.Get("X-Forwarded-For") if forwarded != "" { return forwarded } return r.RemoteAddr } func LogRequest(r *http.Request, userID int) { postLog.Info(fmt.Sprintf("[%s] %s %s - UserID: %d - IP: %s", time.Now().Format("2006-01-02 15:04:05"), r.Method, r.URL.Path, userID, GetClientIP(r), )) } func IntToString(i int) string { return strconv.Itoa(i) }