Compare commits

..

1 Commits

Author SHA1 Message Date
Chris F Ravenscroft d93386123f test: exercise the sqlite plugin in make test
TestSQLitePlugin has never run. It stats a flat bin/sqlite.so, which no
build target produces (make plugin_sqlite writes bin/linuxamd64/sqlite.so,
xgo writes bin/sqlite-linux-amd64.so), so it always took the skip branch.
Even past that it needs a seeded database, and nothing in the repo seeds
one.

seedplugindb stages the plugin at the path the test and
sample-database.cfg both expect, then starts glauth once so the plugin's
CreateSchema builds the tables before inserting rows. Taking the schema
from the plugin rather than duplicating its DDL here keeps the two from
drifting.

Guarded on bin/sqlite-linux-amd64.so existing, so CI - which never builds
plugins - still skips the test exactly as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014L5EoqGWsuZWr8fCVM6izP
2026-09-13 15:09:12 -07:00
6 changed files with 27 additions and 128 deletions
+2 -2
View File
@@ -13,7 +13,7 @@ jobs:
go-version: [1.25.x]
steps:
- name: Install Go
uses: actions/setup-go@v7
uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go-version }}
- name: Updating packages database
@@ -21,7 +21,7 @@ jobs:
- name: Install CLI Dependencies
run: sudo apt-get install -y ldap-utils oathtool libpam0g-dev
- name: Checkout code
uses: actions/checkout@v7
uses: actions/checkout@v4
- name: Fetch Go dependencies
working-directory: ./v2
run: go get -t -v ./...
+4 -4
View File
@@ -24,18 +24,18 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v4
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"
-54
View File
@@ -1,54 +0,0 @@
name: stale
on:
schedule:
# Daily, off the hour to avoid GitHub's scheduling congestion at :00
- cron: '17 4 * * *'
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v11
with:
days-before-stale: 60
days-before-close: 14
stale-issue-label: stale
stale-pr-label: stale
stale-issue-message: >
This issue has had no activity for 60 days and has been marked stale.
It will be closed in 14 days unless there is new activity. If it is
still relevant, a comment saying so is enough to keep it open.
stale-pr-message: >
This pull request has had no activity for 60 days and has been marked
stale. It will be closed in 14 days unless there is new activity. If
you intend to continue the work, a comment saying so is enough to keep
it open.
close-issue-message: >
Closing this issue after 14 days with no further activity. If it is
still relevant, please comment and it can be reopened.
close-pr-message: >
Closing this pull request after 14 days with no further activity.
Please comment if you would like to pick the work back up.
# Never touch anything deliberately kept open.
exempt-issue-labels: 'pinned,security,blocked,help wanted,good first issue'
exempt-pr-labels: 'pinned,security,blocked,dependencies'
exempt-all-milestones: true
# Restarts the clock when someone comments, so an active discussion is
# never swept up.
remove-stale-when-updated: true
# Oldest first, so the genuine backlog is handled before recent items.
ascending: true
+12 -6
View File
@@ -44,11 +44,12 @@ func InitLogging(reqdebug bool, reqsyslog bool, reqstructlog bool) zerolog.Logge
var logr zerolog.Logger
if reqsyslog {
s, err := syslog.New(syslog.LOG_INFO, "glauth")
if err == nil {
logr = zerolog.New(zerolog.SyslogLevelWriter(s)).Level(level).With().Timestamp().Logger()
} else {
if err != nil {
fmt.Println("Unable to write to syslog: ignoring...")
reqsyslog = false
} else {
writers := zerolog.MultiLevelWriter(mainWriter, zerolog.SyslogLevelWriter(s))
logr = zerolog.New(writers).Level(level).With().Timestamp().Logger()
}
}
@@ -56,13 +57,14 @@ func InitLogging(reqdebug bool, reqsyslog bool, reqstructlog bool) zerolog.Logge
logr = zerolog.New(mainWriter).Level(level).With().Timestamp().Logger()
}
log.SetOutput(customWriter{logr: logr})
log.SetOutput(customWriter{logr: logr, structlog: reqstructlog})
return logr
}
type customWriter struct {
logr zerolog.Logger
logr zerolog.Logger
structlog bool
}
func (e customWriter) Write(p []byte) (int, error) {
@@ -74,6 +76,10 @@ func (e customWriter) Write(p []byte) (int, error) {
if msg == "" {
msg = strings.TrimSpace(string(p))
}
e.logr.Info().Msg(msg)
if e.structlog {
fmt.Fprintf(os.Stderr, "{\"level\":\"info\",\"time\":\"%s\",\"message\":\"%s\"}\n", time.Now().Format(time.RFC1123Z), strings.Replace(strings.TrimSpace(msg), `"`, `\"`, -1))
} else {
e.logr.Info().Msg(msg)
}
return len(p), nil
}
-59
View File
@@ -1,59 +0,0 @@
package logging
import (
"bytes"
"encoding/json"
"strings"
"testing"
"github.com/rs/zerolog"
)
// customWriter adapts log output from libraries that emit unstructured text.
// Everything it receives must go through the logger, so that it lands wherever
// the logger points - notably syslog only, when syslog is enabled.
func TestCustomWriterEmitsValidJSONThroughTheLogger(t *testing.T) {
for _, tc := range []struct {
name string
in string
want string
}{
{"plain", "something happened", "something happened"},
{"quotes", `bind for "cn=foo"`, `bind for "cn=foo"`},
{"backslashes", `path C:\Users\x`, `path C:\Users\x`},
{"control characters", "tab\there\nand a newline", "tab\there\nand a newline"},
{
"library timestamp prefix is stripped",
"2026/09/13 16:50:54 connection closed",
"connection closed",
},
} {
t.Run(tc.name, func(t *testing.T) {
var buf bytes.Buffer
w := customWriter{logr: zerolog.New(&buf).With().Timestamp().Logger()}
if _, err := w.Write([]byte(tc.in)); err != nil {
t.Fatalf("Write: %v", err)
}
// One record, one line: an unescaped newline would split this.
if got := strings.Count(strings.TrimRight(buf.String(), "\n"), "\n"); got != 0 {
t.Fatalf("expected a single log line, got %d extra newlines in %q", got, buf.String())
}
var record struct {
Level string `json:"level"`
Message string `json:"message"`
}
if err := json.Unmarshal(buf.Bytes(), &record); err != nil {
t.Fatalf("emitted invalid JSON (%v): %s", err, buf.String())
}
if record.Message != tc.want {
t.Errorf("message = %q, want %q", record.Message, tc.want)
}
if record.Level != "info" {
t.Errorf("level = %q, want %q", record.Level, "info")
}
})
}
}
+9 -3
View File
@@ -4,6 +4,7 @@
package logging
import (
"fmt"
"io"
"log"
"os"
@@ -41,13 +42,14 @@ func InitLogging(reqdebug bool, reqsyslog bool, reqstructlog bool) zerolog.Logge
logr := zerolog.New(mainWriter).Level(level).With().Timestamp().Logger()
log.SetOutput(customWriter{logr: logr})
log.SetOutput(customWriter{logr: logr, structlog: reqstructlog})
return logr
}
type customWriter struct {
logr zerolog.Logger
logr zerolog.Logger
structlog bool
}
func (e customWriter) Write(p []byte) (int, error) {
@@ -59,6 +61,10 @@ func (e customWriter) Write(p []byte) (int, error) {
if msg == "" {
msg = strings.TrimSpace(string(p))
}
e.logr.Info().Msg(msg)
if e.structlog {
fmt.Fprintf(os.Stderr, "{\"level\":\"info\",\"time\":\"%s\",\"message\":\"%s\"}\n", time.Now().Format(time.RFC1123Z), strings.Replace(strings.TrimSpace(msg), `"`, `\"`, -1))
} else {
e.logr.Info().Msg(msg)
}
return len(p), nil
}