fix(t234): log OCR result in diagnostics
This commit is contained in:
@@ -154,9 +154,16 @@ func (manager *SessionManager) EnsureAuthenticated(ctx context.Context) error {
|
||||
return domain.ErrFreightSourceProtocol
|
||||
}
|
||||
code, err := manager.recognizer.Recognize(ctx, image.Content, image.ContentType)
|
||||
if err != nil || !validCaptchaCode(code) {
|
||||
if err != nil {
|
||||
manager.logOCRResultFailed()
|
||||
return domain.ErrFreightSourceOCRInvalid
|
||||
}
|
||||
code = strings.TrimSpace(code)
|
||||
if !validCaptchaCode(code) {
|
||||
manager.logOCRResultInvalid()
|
||||
return domain.ErrFreightSourceOCRInvalid
|
||||
}
|
||||
manager.logOCRResult(code)
|
||||
_, err = manager.Login(ctx, status.CaptchaTicket, code)
|
||||
if errors.Is(err, ErrLoginRejected) {
|
||||
return domain.ErrFreightSourceLoginRejected
|
||||
@@ -479,6 +486,30 @@ func (manager *SessionManager) logERPTransportFailure(request *http.Request) {
|
||||
)
|
||||
}
|
||||
|
||||
func (manager *SessionManager) logOCRResult(value string) {
|
||||
if !manager.diagnosticsOn {
|
||||
return
|
||||
}
|
||||
manager.diagnosticLog(
|
||||
"erp_ocr_result value=" + strconv.Quote(value) +
|
||||
" length=" + strconv.Itoa(len(value)),
|
||||
)
|
||||
}
|
||||
|
||||
func (manager *SessionManager) logOCRResultInvalid() {
|
||||
if !manager.diagnosticsOn {
|
||||
return
|
||||
}
|
||||
manager.diagnosticLog("erp_ocr_result class=invalid")
|
||||
}
|
||||
|
||||
func (manager *SessionManager) logOCRResultFailed() {
|
||||
if !manager.diagnosticsOn {
|
||||
return
|
||||
}
|
||||
manager.diagnosticLog("erp_ocr_result class=failed")
|
||||
}
|
||||
|
||||
func (manager *SessionManager) logERPResponsePreview(
|
||||
request *http.Request,
|
||||
response *http.Response,
|
||||
|
||||
@@ -252,6 +252,7 @@ func TestSessionManagerDiagnosticLogsAreRedacted(t *testing.T) {
|
||||
"erp_request method=GET path=/api/p/code1",
|
||||
"erp_response method=GET path=/api/p/code1 status=200",
|
||||
"body=omitted_non_json",
|
||||
`erp_ocr_result value="1234" length=4`,
|
||||
"erp_request method=POST path=/am/auth/login",
|
||||
"erp_response method=POST path=/am/auth/login status=200",
|
||||
`"status":false`,
|
||||
@@ -270,6 +271,67 @@ func TestSessionManagerDiagnosticLogsAreRedacted(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSessionManagerDiagnosticLogsHideInvalidOCRResults(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
recognizer *fixedRecognizer
|
||||
wantEvent string
|
||||
secret string
|
||||
}{
|
||||
{
|
||||
name: "invalid text",
|
||||
recognizer: &fixedRecognizer{code: "private\nOCR output"},
|
||||
wantEvent: "erp_ocr_result class=invalid",
|
||||
secret: "private",
|
||||
},
|
||||
{
|
||||
name: "recognizer failure",
|
||||
recognizer: &fixedRecognizer{err: errors.New("private OCR response")},
|
||||
wantEvent: "erp_ocr_result class=failed",
|
||||
secret: "private",
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(
|
||||
writer http.ResponseWriter,
|
||||
request *http.Request,
|
||||
) {
|
||||
if request.URL.Path != CaptchaPath {
|
||||
writer.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
writer.Header().Set("Content-Type", "image/png")
|
||||
_, _ = writer.Write([]byte("private-captcha-image"))
|
||||
}))
|
||||
defer server.Close()
|
||||
var events []string
|
||||
manager, err := NewSessionManager(SessionConfig{
|
||||
BaseURL: server.URL,
|
||||
Username: "test-user",
|
||||
Password: "test-password",
|
||||
Timeout: time.Second,
|
||||
AllowInsecureHTTP: true,
|
||||
CaptchaRecognizer: testCase.recognizer,
|
||||
DiagnosticLogger: func(event string) {
|
||||
events = append(events, event)
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewSessionManager() error = %v", err)
|
||||
}
|
||||
if err := manager.EnsureAuthenticated(context.Background()); !errors.Is(err, domain.ErrFreightSourceOCRInvalid) {
|
||||
t.Fatalf("EnsureAuthenticated() error = %v", err)
|
||||
}
|
||||
actual := strings.Join(events, "\n")
|
||||
if !strings.Contains(actual, testCase.wantEvent) || strings.Contains(actual, testCase.secret) ||
|
||||
strings.Contains(actual, "private-captcha-image") || strings.Contains(actual, "test-password") {
|
||||
t.Fatalf("diagnostic log = %s", actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fixedRecognizer struct {
|
||||
code string
|
||||
err error
|
||||
|
||||
Reference in New Issue
Block a user