package main import ( "fmt" "net/http" "strconv" "strings" "time" ) func isMethodAllowed(response *http.ResponseWriter, request *http.Request) bool { if request.Method != http.MethodPost { http.Error(*response, "POST only", http.StatusMethodNotAllowed) return false } return true } func parseRgb(str string) ([3]uint8, error) { parts := strings.SplitN(str, ",", 4) if len(parts) != 3 { return [3]uint8{}, fmt.Errorf("invalid rgb") } var rgb [3]uint8 for i, p := range parts { n, err := strconv.ParseUint(strings.TrimSpace(p), 10, 8) if err != nil { return [3]uint8{}, fmt.Errorf("invalid component %d: %w", i, err) } rgb[i] = uint8(n) } return rgb, nil } func HttpHandleNewUser(response http.ResponseWriter, request *http.Request) { if !isMethodAllowed(&response, request) { return } username := request.FormValue("username") if len(username) < 4 { http.Error(response, "no or short username", http.StatusBadRequest) return } password := request.FormValue("password") if len(password) < 8 { http.Error(response, "no or short password", http.StatusBadRequest) return } color, err := parseRgb(request.FormValue("color")) if err != nil { http.Error(response, "bad color", http.StatusBadRequest) } hashedPassword, err := PasswordHash(password) if err != nil { http.Error(response, "internal server error", http.StatusInternalServerError) return } newClient := &Client{ Name: username, PasswordHash: hashedPassword, Color: color, CreatedAt: time.Now(), } ctx := request.Context() err = DbSaveClientWithoutGroups(ctx, newClient) if err != nil { http.Error(response, "name taken", http.StatusInternalServerError) return } } func HttpHandleLogin(response http.ResponseWriter, request *http.Request) { if !isMethodAllowed(&response, request) { return } username := request.FormValue("username") if len(username) < 4 { http.Error(response, "no or short username", http.StatusBadRequest) return } var client = Client{Name: username} if len(client.Name) < 8 { http.Error(response, "no or short password", http.StatusBadRequest) return } ctx := request.Context() err := DbSetClientByName(ctx, &client) if err != nil { return } _, err = CacheGetClientById(client.Id) if err == nil { otherLoggedIn, err := CacheGetClientById(client.Id) if err == nil { otherLoggedIn.WsConn.CloseNow() } } token, err := TokenCreate(client.Id) if err != nil { http.Error(response, "internal server error", http.StatusInternalServerError) } response.Write([]byte(token)) } func HttpHandleGroupCreate(response http.ResponseWriter, request *http.Request) { if !isMethodAllowed(&response, request) { return } }