mirror of
https://github.com/tiennm99/tiennm99bot.git
synced 2026-10-14 12:17:10 +00:00
fix(monkeyd): make /monkeyd_crawl public and fix PDF font resolution
Advance the crawler submodule to the fix for the production failure "stat usr/share/fonts/...: no such file or directory": the PDF writer was handing fpdf a font path, and fpdf rewrote the absolute path into a working-directory-relative one. Font data is now passed as bytes, with a fallback font compiled into the binary when the host has none. The runtime image therefore no longer installs DejaVuSans, which also removes the font layer from the builder stage. /monkeyd_crawl becomes public. The host allowlist and the single in-flight export were already the controls that bound its cost; they now carry that job alone, so both are load-bearing.
This commit is contained in:
1 parent
af1e8776af
commit
67934adfa0
6 files changed
+45
-34
No files matched your search
@@ -246,15 +246,24 @@ func TestCrawl_RepliesBusyWhileAnotherExportRuns(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// A Protected command must not respond at all to an unauthorized sender, or its
|
||||
// existence leaks.
|
||||
func TestCrawl_SilentForUnauthorizedSender(t *testing.T) {
|
||||
rb, _ := install(t, 999)
|
||||
rb.Bot.ProcessUpdate(context.Background(),
|
||||
testutil.NewPrivateMessage(12345, "/monkeyd_crawl "+testNovelURL))
|
||||
// The command is public: a sender who is neither owner nor admin must still get
|
||||
// a reply, including in a group.
|
||||
func TestCrawl_AvailableToAnySender(t *testing.T) {
|
||||
rb, r := install(t, 999)
|
||||
dir := t.TempDir()
|
||||
r.exporter = func(context.Context, export.Request) (*export.Result, error) {
|
||||
return stubPDF(t, dir, "Example-Novel.pdf", 2048), nil
|
||||
}
|
||||
|
||||
if calls := rb.Sent(); len(calls) != 0 {
|
||||
t.Errorf("expected no reply to an unauthorized sender, got %+v", calls)
|
||||
rb.Bot.ProcessUpdate(context.Background(),
|
||||
testutil.NewGroupMessage(-100, 12345, "/monkeyd_crawl "+testNovelURL))
|
||||
|
||||
calls := rb.Sent()
|
||||
if len(calls) == 0 {
|
||||
t.Fatal("a non-admin sender got no reply from a public command")
|
||||
}
|
||||
if last := calls[len(calls)-1]; last.Method != "sendDocument" {
|
||||
t.Errorf("last call = %q, want sendDocument", last.Method)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,8 +276,8 @@ func TestRegistration(t *testing.T) {
|
||||
if cmd.Name != commandName {
|
||||
t.Errorf("Name = %q, want %q", cmd.Name, commandName)
|
||||
}
|
||||
if cmd.Visibility != modules.VisibilityProtected {
|
||||
t.Errorf("Visibility = %v, want Protected", cmd.Visibility)
|
||||
if cmd.Visibility != modules.VisibilityPublic {
|
||||
t.Errorf("Visibility = %v, want Public", cmd.Visibility)
|
||||
}
|
||||
if cmd.Parameters != "<url>" {
|
||||
t.Errorf("Parameters = %q, want %q", cmd.Parameters, "<url>")
|
||||
|
||||
@@ -39,9 +39,11 @@ func newModule(r *runner) modules.Module {
|
||||
Commands: []modules.Command{
|
||||
{
|
||||
Name: commandName,
|
||||
Visibility: modules.VisibilityProtected,
|
||||
// One invocation makes hundreds of outbound requests over
|
||||
// several minutes, so it stays off the public surface.
|
||||
Visibility: modules.VisibilityPublic,
|
||||
// Public despite being expensive: one invocation makes
|
||||
// hundreds of outbound requests over several minutes. The
|
||||
// host allowlist and the single in-flight export are what
|
||||
// bound the cost, so both are load-bearing here.
|
||||
Description: "Export a " + AllowedHostsHint + " novel as a PDF",
|
||||
Parameters: "<url>",
|
||||
Handler: r.handle,
|
||||
|
||||
Reference in new issue
Block a user