package main import ( "crypto/rand" "database/sql" "encoding/hex" "encoding/json" "fmt" "log" "math/big" "net/http" "strings" "time" _ "github.com/mattn/go-sqlite3" ) type User struct { UserID string `json:"user_id"` Username string `json:"username"` } type RegistrationResponse struct { UserID string `json:"user_id"` } type ProfileRequest struct { UserID string `json:"user_id"` } type ProfileResponse struct { Username string `json:"username"` } var db *sql.DB func generateUsername() (string, error) { adjectives := []string{ "freaky", "suspicious", "malicious", "supersticious", "handsome", "ugly", "crazy", "demonic", "peeping", "slippery", "mysterious", "spooky", "creepy", "sinister", "ghoulish", "macabre", "eerie", "pessimistic", "frightening", "grotesque", "haunted", "infernal", "menacing", "morose", "nefarious", "nightmarish", "obscure", "ominous", "phantasmagoric", "pallid", "perilous", "phantom", "aberrant", "bizarre", "chilling", "cryptic", "dark", "dreadful", "obsolete", "greasy", "bald", "putrid", "old", } words := []string{ "magician", "welder", "wizard", "criminal", "rat", "castle", "droid", "robot", "cyborg", "joe", "bob", "tom", "builder", "architect", "troll", "ogre", "nomad", "bohemian", "skeleton", "goblin", "monster", "engineer", "dude", "guy", "mob", "creep", "juice", "smoke", "potion", "fart", "mage", "vermin", "crook", "flunkey", "insect", "bug", "handyman", } index1Big, err := rand.Int(rand.Reader, big.NewInt(int64(len(adjectives)))) if err != nil { return "", fmt.Errorf("failed to generate random index for array1: %w", err) } index1 := int(index1Big.Int64()) index2Big, err := rand.Int(rand.Reader, big.NewInt(int64(len(words)))) if err != nil { return "", fmt.Errorf("failed to generate random index for array2: %w", err) } index2 := int(index2Big.Int64()) randomNumberBig, err := rand.Int(rand.Reader, big.NewInt(101)) if err != nil { return "", fmt.Errorf("failed to generate random number: %w", err) } randomNumber := randomNumberBig.Int64() username := fmt.Sprintf("%s_%s%d", adjectives[index1], words[index2], randomNumber) return username, nil } func generateSecureUserID() (string, error) { b := make([]byte, 8) _, err := rand.Read(b) if err != nil { return "", err } return hex.EncodeToString(b), nil } //func validateUsername(username string) error { // if len(username) < 3 || len(username) > 32 { // return fmt.Errorf("[-] username must be between 3 and 32 characters") // } // // pattern := `^[a-zA-Z0-9_]+$` // match, err := regexp.MatchString(pattern, username) // if err != nil { // return fmt.Errorf("[-] error validating username") // } // if !match { // return fmt.Errorf("[-] username can only contain letters, numbers, and underscores") // } // // return nil //} func InitDB(dbPath string) (*sql.DB, error) { db, err := sql.Open("sqlite3", dbPath) if err != nil { return nil, fmt.Errorf("failed to open db: %v", err) } _, err = db.Exec(` CREATE TABLE IF NOT EXISTS users ( user_id TEXT PRIMARY KEY CHECK(length(user_id) = 16), username TEXT NOT NULL UNIQUE CHECK(length(username) >= 3 AND length(username) <= 32), created_at DATETIME DEFAULT CURRENT_TIMESTAMP ) `) if err != nil { db.Close() return nil, fmt.Errorf("failed to create users table: %v", err) } return db, nil } func greet(w http.ResponseWriter, r *http.Request) { println("[+] ping") fmt.Fprintf(w, "[+] enxos server %s", time.Now()) } func u_profile(w http.ResponseWriter, r *http.Request) { println("[+] u_profile") if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } var profRequest ProfileRequest err := json.NewDecoder(r.Body).Decode(&profRequest) if err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } profRequest.UserID = strings.TrimSpace(profRequest.UserID) var username string err = db.QueryRow("SELECT username FROM users WHERE user_id = ?", profRequest.UserID).Scan(&username) if err != nil { http.Error(w, "Database error", http.StatusInternalServerError) return } if strings.Compare(strings.TrimSpace(username), "") == 0 { http.Error(w, "UserID not found", http.StatusBadRequest) return } response := ProfileResponse{ Username: username, } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(response) } func u_register(w http.ResponseWriter, r *http.Request) { println("[+] u_register") if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } username, err := generateUsername() if err != nil { http.Error(w, "Failed to generate username", http.StatusInternalServerError) return } userid, err := generateSecureUserID() if err != nil { http.Error(w, "Failed to generate user ID", http.StatusInternalServerError) return } _, err = db.Exec("INSERT INTO users (user_id, username) VALUES (?, ?)", userid, username) if err != nil { http.Error(w, "Failed to create user", http.StatusInternalServerError) return } response := RegistrationResponse{ UserID: userid, } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(response) } func main() { const dbPath = "./users.db" var err error db, err = InitDB(dbPath) if err != nil { log.Fatalf("DB Initialization failed: %v", err) } err = db.Ping() if err != nil { log.Fatal(err) } http.HandleFunc("/", greet) http.HandleFunc("/u/profile", u_profile) http.HandleFunc("/u/register", u_register) //http.ListenAndServe(":8801", nil) server := &http.Server{ Addr: ":8801", ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, } log.Printf("[+] enxos server starting on %s", server.Addr) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("[-] server failed to start: %v", err) } }