Files
geo/server/internal/tenant/app/meijiequan_challenge_resolver.go
T

40 lines
1.4 KiB
Go
Raw Normal View History

package app
import (
"bytes"
"context"
"errors"
"fmt"
// image/png is registered by the digitocr package; jpeg/gif are registered
// here so a future change of the captcha format still decodes.
_ "image/gif"
_ "image/jpeg"
"github.com/geo-platform/tenant-api/internal/shared/digitocr"
)
// meijiequanChallengeDigits is the fixed length of the meijiequan login captcha.
const meijiequanChallengeDigits = 4
var errMeijiequanChallengeEmpty = errors.New("meijiequan challenge image is empty")
// DigitOCRMeijiequanChallengeCodeResolver decodes the meijiequan numeric login
// captcha locally via the digitocr template matcher, enabling unattended login
// without an external OCR service.
type DigitOCRMeijiequanChallengeCodeResolver struct{}
// ResolveCode recognizes the digits in the captcha image. A decode failure is
// returned as a non-challenge error so the login flow retries with a fresh
// captcha rather than giving up immediately (as the manual resolver does).
func (DigitOCRMeijiequanChallengeCodeResolver) ResolveCode(_ context.Context, challenge MeijiequanChallenge) (string, error) {
if len(challenge.Image) == 0 {
return "", errMeijiequanChallengeEmpty
}
code, err := digitocr.RecognizeReader(bytes.NewReader(challenge.Image), digitocr.Options{Digits: meijiequanChallengeDigits})
if err != nil {
return "", fmt.Errorf("digitocr resolve meijiequan challenge: %w", err)
}
return code, nil
}