...

Source file src/codeberg.org/tslocum/sriracha/internal/server/server_captcha.go

Documentation: codeberg.org/tslocum/sriracha/internal/server

     1  package server
     2  
     3  import (
     4  	"fmt"
     5  	"image/color"
     6  	"log"
     7  	"net/http"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"time"
    12  
    13  	"codeberg.org/tslocum/sriracha/internal/database"
    14  	. "codeberg.org/tslocum/sriracha/model"
    15  	. "codeberg.org/tslocum/sriracha/util"
    16  	"github.com/steambap/captcha"
    17  )
    18  
    19  var captchaPalette = []color.Color{
    20  	color.RGBA{0, 0, 0, 255},
    21  }
    22  
    23  func (s *Server) serveCAPTCHA(db *database.DB, w http.ResponseWriter, r *http.Request) {
    24  	const (
    25  		width, height = 225, 40
    26  		characters    = "ABCDHKMNSTUVWXYZ"
    27  		refreshLimit  = 3
    28  	)
    29  
    30  	ipHash := s.hashIP(r)
    31  
    32  	c := db.GetCAPTCHA(ipHash)
    33  	if c != nil {
    34  		queryValues := r.URL.Query()
    35  		if len(queryValues["new"]) == 0 || c.Refresh >= refreshLimit {
    36  			http.Redirect(w, r, fmt.Sprintf("/captcha/%s.png", c.Image), http.StatusFound)
    37  			return
    38  		}
    39  	}
    40  
    41  	challenge, err := captcha.New(width, height, func(options *captcha.Options) {
    42  		options.CharPreset = characters
    43  		options.TextLength = 5
    44  		options.Noise = 1
    45  		options.CurveNumber = 3
    46  		options.Palette = captchaPalette
    47  		options.BackgroundColor = color.Transparent
    48  	})
    49  	if err != nil {
    50  		log.Fatal(err)
    51  	}
    52  
    53  	var oldImage string
    54  	if c == nil {
    55  		c = &CAPTCHA{
    56  			IP:        ipHash,
    57  			Timestamp: time.Now().Unix(),
    58  		}
    59  	} else {
    60  		oldImage = c.Image
    61  		c.Refresh++
    62  	}
    63  
    64  	c.Image = db.NewCAPTCHAImage()
    65  	c.Text = strings.ToLower(challenge.Text)
    66  
    67  	f, err := os.OpenFile(filepath.Join(s.config.Root, "captcha", c.Image+".png"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, NewFilePermission)
    68  	if err != nil {
    69  		log.Fatal(err)
    70  	}
    71  	challenge.WriteImage(f)
    72  	f.Close()
    73  
    74  	if oldImage != "" {
    75  		os.Remove(filepath.Join(s.config.Root, "captcha", oldImage+".png"))
    76  	}
    77  
    78  	if oldImage == "" {
    79  		db.AddCAPTCHA(c)
    80  	} else {
    81  		db.UpdateCAPTCHA(c)
    82  	}
    83  
    84  	http.Redirect(w, r, fmt.Sprintf("/captcha/%s.png", c.Image), http.StatusFound)
    85  }
    86  

View as plain text