gotcha

package module
v0.0.0-...-2b8b345 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 16, 2020 License: MIT Imports: 24 Imported by: 0

README

gotcha

Gotcha is a captcha generator/validation server.

Very much a work in progress.

Roadmap for a usable product

  • Implement other font rendering methods
  • Server security by identifying clients
    • Via secret key
    • Via certs

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoSources sources not set, select one of Random, Math or QuestionBank.
	ErrNoSources = errors.New("sources not set, select one of Random, Math or QuestionBank")
	// ErrLangEmpty lang is empty.
	ErrLangEmpty = errors.New("lang is empty")
)
View Source
var (
	ErrNotFound            = &ErrResponse{HTTPStatusCode: 404, StatusText: "Resource not found."}
	ErrInternalServerError = &ErrResponse{HTTPStatusCode: 500, StatusText: "Server error."}
	ErrIncorrectAnswer     = &ErrResponse{HTTPStatusCode: 403, StatusText: "Incorrect answer."}
)
View Source
var (

	// DefaultManager default settings.
	DefaultManager = &Manager{
		Languages:           defaultLangs,
		Sources:             Math | Random,
		Math:                NewSymbols(defaultLangs...),
		Bank:                NewBank(defaultLangs...),
		defaultExpiry:       10 * time.Minute,
		lifetimeAfterPassed: 2 * time.Minute,
		Store:               DefaultStore,
	}
)

Functions

func AddToContext

func AddToContext(ctx context.Context, keyValuePair ...interface{}) (context.Context, error)

AddToContext is a helper function that adds the values in keyValuePair to ctx. Keys are even indexes (0 is considered even), values are odd indexes.

func ErrInvalidRequest

func ErrInvalidRequest(err error) render.Renderer

func ErrRender

func ErrRender(err error) render.Renderer

Types

type Bank

type Bank struct {
	Values map[string][]*Captcha
}

Bank contains arrays a map[string][]*Captcha, under each language. The captchas only contain questions and answers, their Audio and image fields will not be populated until it is requested.

func NewBank

func NewBank(langs ...string) *Bank

NewBank initializes a *Bank with langs.

type Captcha

type Captcha struct {
	// ID of this Captcha.
	ID uint32 `json:"id,omitempty"`
	// Img url to image file on server.
	Image string `json:"image-url,omitempty"`
	// Passed status of this captcha.
	Passed   bool   `json:"passed"`
	ClientID string `json:"client-id"`
	// Lang language.
	Lang string `json:"language,omitempty"`
	// Audio url to audio file on server.
	Audio string `json:"audio-url,omitempty"`
	// Question the question posed in the captcha.
	Question string `json:"question,omitempty"`
	// Ans slice of acceptable answers.
	Answers []string `json:"answers,omitempty"`
	// Expiry when this Captcha is invalid and needs to be refreshed.
	Expiry time.Time `json:"expiry,omitempty"`
}

func (*Captcha) Match

func (q *Captcha) Match(ans string) bool

type CaptchaResponse

type CaptchaResponse struct {
	*Captcha
}

func NewCaptchaResponse

func NewCaptchaResponse(c *Captcha) *CaptchaResponse

func (*CaptchaResponse) Render

type Challenge

type Challenge interface {
	// Match check whether the answer passes the test.
	Match(answer string) bool
}

type Challenger

type Challenger interface {
	// Gen generates a Challenge based on parameters in Gen.
	Gen(ctx context.Context) (*Captcha, error)
	Refresh(captchaID uint32) (*Captcha, error)
	Status(captchaID uint32) bool
	// GC garbage collects expired captchas. Needs to run in a goroutine to clean
	// expired captchas. It call the store's GC method every unit.
	GC(unit time.Duration, err chan<- error, cancel <-chan struct{})
}

type CheckRequest

type CheckRequest struct {
	Answer string `json:"challenge-response"`
}

func (*CheckRequest) Bind

func (c *CheckRequest) Bind(r *http.Request) error

type CtxKey

type CtxKey uint8
const (
	Language CtxKey = iota + 1
	Expiry
	NoGzip
	CaptchaCtxKey
)

type ErrResponse

type ErrResponse struct {
	Err            error `json:"-"` // low-level runtime error
	HTTPStatusCode int   `json:"-"` // http response status code

	StatusText string `json:"status"`          // user-level status message
	ErrorText  string `json:"error,omitempty"` // application-level error message, for debugging
}

func (*ErrResponse) Render

func (e *ErrResponse) Render(w http.ResponseWriter, r *http.Request) error

type Generator

type Generator interface {
	GenerateChallenge(noise float64) (*Captcha, error)
}

type Manager

type Manager struct {
	Challenger
	// Sources sources the manager will use for challenges.
	Sources Source
	// Languages the manager will accept and generate challenges in.
	Languages []string
	// Bank question bank to use.
	Bank *Bank
	// Math set of math symbols to use.
	Math        *Symbols
	Store       Storer
	FileStorage gostorage.Driver
	// contains filtered or unexported fields
}

func NewManager

func NewManager(opts ...Option) *Manager

NewManager returns a default manager modified with opts. Panics on error.

func (*Manager) CaptchaCtx

func (m *Manager) CaptchaCtx(next http.Handler) http.Handler

func (*Manager) CheckCaptcha

func (m *Manager) CheckCaptcha(w http.ResponseWriter, r *http.Request)

func (*Manager) GC

func (m *Manager) GC(unit time.Duration, errChan chan<- error, cancel <-chan struct{})

GC needs to be run in a goroutine to clean expired captcahs. It'll start a time.Ticker every unit and periodically call the store GC method.

func (*Manager) Gen

func (m *Manager) Gen(ctx context.Context) (c *Captcha, err error)

func (*Manager) NewCaptcha

func (m *Manager) NewCaptcha(w http.ResponseWriter, r *http.Request)

func (*Manager) Refresh

func (m *Manager) Refresh(captchaID uint32) (*Captcha, error)

func (*Manager) RefreshCaptcha

func (m *Manager) RefreshCaptcha(w http.ResponseWriter, r *http.Request)

func (*Manager) Router

func (m *Manager) Router(ctx context.Context) http.Handler

type MathSymbol

type MathSymbol struct {
	Human  string `json:"human"`
	Symbol string `json:"symbol"`
}

func (*MathSymbol) HumanOrSymbol

func (m *MathSymbol) HumanOrSymbol() string

HumanOrSymbol 50/50 chance of either.

func (*MathSymbol) String

func (m *MathSymbol) String() string

String always return the symbol be parsed.

type OKResponse

type OKResponse struct {
	Status string `json:"Status"`
}

func (*OKResponse) Render

func (ok *OKResponse) Render(w http.ResponseWriter, r *http.Request) error

type Option

type Option func(*Manager)

func WithExpiry

func WithExpiry(expiry time.Duration) Option

WithExpiry sets captcha expiration to expiry.

func WithLifetime

func WithLifetime(lifetime time.Duration) Option

WithLifetime sets lifetime of captchas, once passed, to lifetime.

func WithMath

func WithMath(symbols *Symbols) Option

WithMath appends Math to the sources and replaces the default math symbols with the passed symbols.

func WithMountPoint

func WithMountPoint(v string) Option

WithMountPoint sets the mountpoint to v.

func WithNoGzip

func WithNoGzip() Option

WithNoGzip serve the static assets without gzipping them.

func WithQuestionBank

func WithQuestionBank(bank *Bank) Option

func WithSources

func WithSources(s Source) Option

WithSources sets the source to s.

func WithStorage

func WithStorage(storageURL string) Option

WithStorage sets the Store to the storageURL. See https://github.com/djangulo/go-storage for viable connection strings. Panics on error.

type Source

type Source int
const (
	// Math randomly generate word math questions "six plus 2", "10 minus five"
	Math Source = 1 << iota
	// Random randomly generate 5 alphanumeric strings
	Random
	// QuestionBank use a provided question bank of the type
	// "what color are the smurfs", ans "blue"
	QuestionBank
)

type Storer

type Storer interface {
	Create(c *Captcha) error
	Get(id uint32) (*Captcha, error)
	Update(id uint32, c *Captcha) error
	Delete(id uint32) error
	// GC garbage collects expired captchas. Needs to run in a goroutine to clean
	// expired captchas.
	GC() error
}

Storer interface for persistent storage.

var DefaultStore Storer = &defaultStore{
	captchas: make(map[uint32]*Captcha),
}

type Symbols

type Symbols struct {
	Values map[string][]*MathSymbol
}

Symbols holds MathSymbol definitions under each language. e.g. Symbols.Values["en"].

func NewSymbols

func NewSymbols(langs ...string) *Symbols

NewSymbols initializes a *Symbols with langs.

Directories

Path Synopsis
_examples
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL