...

Source file src/codeberg.org/tslocum/sriracha/internal/database/database_captcha.go

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

     1  package database
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"encoding/base64"
     7  	"log"
     8  	"time"
     9  
    10  	. "codeberg.org/tslocum/sriracha/model"
    11  	"github.com/jackc/pgx/v5"
    12  )
    13  
    14  func (db *DB) AddCAPTCHA(c *CAPTCHA) {
    15  	_, err := db.conn.Exec(context.Background(), "INSERT INTO captcha VALUES ($1, $2, $3, $4, $5)",
    16  		c.IP,
    17  		c.Timestamp,
    18  		c.Refresh,
    19  		c.Image,
    20  		c.Text,
    21  	)
    22  	if err != nil {
    23  		log.Fatalf("failed to insert captcha: %s", err)
    24  	}
    25  }
    26  
    27  func (db *DB) GetCAPTCHA(ip string) *CAPTCHA {
    28  	c := &CAPTCHA{}
    29  	err := scanCAPTCHA(c, db.conn.QueryRow(context.Background(), "SELECT * FROM captcha WHERE ip = $1", ip))
    30  	if err == pgx.ErrNoRows {
    31  		return nil
    32  	} else if err != nil {
    33  		log.Fatalf("failed to select captcha: %s", err)
    34  	}
    35  	return c
    36  }
    37  
    38  func (db *DB) UpdateCAPTCHA(c *CAPTCHA) {
    39  	_, err := db.conn.Exec(context.Background(), "UPDATE captcha SET refresh = $1, image = $2, text = $3 WHERE ip = $4", c.Refresh, c.Image, c.Text, c.IP)
    40  	if err != nil {
    41  		log.Fatal(err)
    42  	}
    43  }
    44  
    45  func (db *DB) ExpiredCAPTCHAs() []*CAPTCHA {
    46  	const oneDay = 60 * 60 * 24
    47  	rows, err := db.conn.Query(context.Background(), "SELECT * FROM captcha WHERE timestamp <= $1", time.Now().Unix()-oneDay)
    48  	if err != nil {
    49  		log.Fatalf("failed to select expired captchas: %s", err)
    50  	}
    51  	var captchas []*CAPTCHA
    52  	for rows.Next() {
    53  		c := &CAPTCHA{}
    54  		err := scanCAPTCHA(c, rows)
    55  		if err != nil {
    56  			log.Fatalf("failed to select expired captchas: %s", err)
    57  		}
    58  		captchas = append(captchas, c)
    59  	}
    60  	return captchas
    61  }
    62  
    63  func (db *DB) DeleteCAPTCHA(ip string) {
    64  	if ip == "" {
    65  		return
    66  	}
    67  
    68  	_, err := db.conn.Exec(context.Background(), "DELETE FROM captcha WHERE ip = $1", ip)
    69  	if err != nil {
    70  		log.Fatalf("failed to delete captcha: %s", err)
    71  	}
    72  }
    73  
    74  func (db *DB) NewCAPTCHAImage() string {
    75  	const keyLength = 48
    76  	buf := make([]byte, keyLength)
    77  	for {
    78  		_, err := rand.Read(buf)
    79  		if err != nil {
    80  			panic(err)
    81  		}
    82  		imageName := base64.URLEncoding.EncodeToString(buf)
    83  
    84  		var count int
    85  		err = db.conn.QueryRow(context.Background(), "SELECT COUNT(*) FROM captcha WHERE image = $1", imageName).Scan(&count)
    86  		if err != nil {
    87  			log.Fatalf("failed to select number of accounts with session key: %s", err)
    88  		} else if count == 0 {
    89  			return imageName
    90  		}
    91  	}
    92  }
    93  
    94  func scanCAPTCHA(c *CAPTCHA, row pgx.Row) error {
    95  	return row.Scan(
    96  		&c.IP,
    97  		&c.Timestamp,
    98  		&c.Refresh,
    99  		&c.Image,
   100  		&c.Text,
   101  	)
   102  }
   103  

View as plain text