Skip to content

Commit a7f85c3

Browse files
committed
feat(http): add options to disable GoogleReader/Fever/API
Some users aren't using those, and it thus makes sense to provide a way to disable them, as they expose quite a lot of sensitive-ish features.
1 parent 2e26f5c commit a7f85c3

File tree

5 files changed

+111
-3
lines changed

5 files changed

+111
-3
lines changed

internal/config/config_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,3 +2104,57 @@ func TestInvalidHTTPClientProxy(t *testing.T) {
21042104
t.Fatalf(`Expected error for invalid HTTP_CLIENT_PROXY value, but got none`)
21052105
}
21062106
}
2107+
2108+
func TestDisableAPI(t *testing.T) {
2109+
os.Clearenv()
2110+
os.Setenv("DISABLE_API", "1")
2111+
2112+
parser := NewParser()
2113+
opts, err := parser.ParseEnvironmentVariables()
2114+
if err != nil {
2115+
t.Fatalf(`Parsing failure: %v`, err)
2116+
}
2117+
2118+
expected := true
2119+
result := opts.DisableAPI()
2120+
2121+
if result != expected {
2122+
t.Fatalf(`Unexpected DISABLE_API value, got %v instead of %v`, result, expected)
2123+
}
2124+
}
2125+
2126+
func TestDisableGoogleReaderAPI(t *testing.T) {
2127+
os.Clearenv()
2128+
os.Setenv("DISABLE_GOOGLEREADER_API", "1")
2129+
2130+
parser := NewParser()
2131+
opts, err := parser.ParseEnvironmentVariables()
2132+
if err != nil {
2133+
t.Fatalf(`Parsing failure: %v`, err)
2134+
}
2135+
2136+
expected := true
2137+
result := opts.DisableGoogleReaderAPI()
2138+
2139+
if result != expected {
2140+
t.Fatalf(`Unexpected DISABLE_API value, got %v instead of %v`, result, expected)
2141+
}
2142+
}
2143+
2144+
func TestDisableFeverAPI(t *testing.T) {
2145+
os.Clearenv()
2146+
os.Setenv("DISABLE_FEVER_API", "1")
2147+
2148+
parser := NewParser()
2149+
opts, err := parser.ParseEnvironmentVariables()
2150+
if err != nil {
2151+
t.Fatalf(`Parsing failure: %v`, err)
2152+
}
2153+
2154+
expected := true
2155+
result := opts.DisableFeverAPI()
2156+
2157+
if result != expected {
2158+
t.Fatalf(`Unexpected DISABLE_API value, got %v instead of %v`, result, expected)
2159+
}
2160+
}

internal/config/options.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ const (
8989
defaultWatchdog = true
9090
defaultInvidiousInstance = "yewtu.be"
9191
defaultWebAuthn = false
92+
defaultDisableFeverAPI = false
93+
defaultDisableGoogleReaderAPI = false
94+
defaultDisableAPI = false
9295
)
9396

9497
var defaultHTTPClientUserAgent = "Mozilla/5.0 (compatible; Miniflux/" + version.Version + "; +https://miniflux.app)"
@@ -179,6 +182,9 @@ type options struct {
179182
invidiousInstance string
180183
mediaProxyPrivateKey []byte
181184
webAuthn bool
185+
disableFeverAPI bool
186+
disableGoogleReaderAPI bool
187+
disableAPI bool
182188
}
183189

184190
// NewOptions returns Options with default values.
@@ -259,6 +265,9 @@ func NewOptions() *options {
259265
invidiousInstance: defaultInvidiousInstance,
260266
mediaProxyPrivateKey: crypto.GenerateRandomBytes(16),
261267
webAuthn: defaultWebAuthn,
268+
disableFeverAPI: defaultDisableFeverAPI,
269+
disableGoogleReaderAPI: defaultDisableGoogleReaderAPI,
270+
disableAPI: defaultDisableAPI,
262271
}
263272
}
264273

@@ -666,6 +675,21 @@ func (o *options) WebAuthn() bool {
666675
return o.webAuthn
667676
}
668677

678+
// DisableGoogleReaderAPI returns true if the Google Reader API should be disabled
679+
func (o *options) DisableGoogleReaderAPI() bool {
680+
return o.disableGoogleReaderAPI
681+
}
682+
683+
// DisableFeverAPI returns true if the Fever API should be disabled
684+
func (o *options) DisableFeverAPI() bool {
685+
return o.disableFeverAPI
686+
}
687+
688+
// DisableAPI returns true if the API should be disabled
689+
func (o *options) DisableAPI() bool {
690+
return o.disableAPI
691+
}
692+
669693
// FilterEntryMaxAgeDays returns the number of days after which entries should be retained.
670694
func (o *options) FilterEntryMaxAgeDays() int {
671695
return o.filterEntryMaxAgeDays
@@ -780,6 +804,9 @@ func (o *options) SortedOptions(redactSecret bool) []*option {
780804
"YOUTUBE_API_KEY": redactSecretValue(o.youTubeApiKey, redactSecret),
781805
"YOUTUBE_EMBED_URL_OVERRIDE": o.youTubeEmbedUrlOverride,
782806
"WEBAUTHN": o.webAuthn,
807+
"DISABLE_FEVER_API": o.disableFeverAPI,
808+
"DISABLE_GOOGLEREADER_API": o.disableGoogleReaderAPI,
809+
"DISABLE_API": o.disableAPI,
783810
}
784811

785812
keys := make([]string, 0, len(keyValues))

internal/config/parser.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ func (p *parser) parseLines(lines []string) (err error) {
115115
p.opts.HTTPS = parseBool(value, defaultHTTPS)
116116
case "DISABLE_SCHEDULER_SERVICE":
117117
p.opts.schedulerService = !parseBool(value, defaultSchedulerService)
118+
case "DISABLE_API":
119+
p.opts.disableAPI = parseBool(value, defaultDisableAPI)
120+
case "DISABLE_FEVER_API":
121+
p.opts.disableFeverAPI = parseBool(value, defaultDisableFeverAPI)
122+
case "DISABLE_GOOGLEREADER_API":
123+
p.opts.disableGoogleReaderAPI = parseBool(value, defaultDisableGoogleReaderAPI)
118124
case "DISABLE_HTTP_SERVICE":
119125
p.opts.httpService = !parseBool(value, defaultHTTPService)
120126
case "CERT_FILE":

internal/http/server/httpd.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,15 @@ func setupHandler(store *storage.Storage, pool *worker.Pool) *mux.Router {
242242

243243
subrouter.Use(middleware)
244244

245-
fever.Serve(subrouter, store)
246-
googlereader.Serve(subrouter, store)
247-
api.Serve(subrouter, store, pool)
245+
if !config.Opts.DisableFeverAPI() {
246+
fever.Serve(subrouter, store)
247+
}
248+
if !config.Opts.DisableGoogleReaderAPI() {
249+
googlereader.Serve(subrouter, store)
250+
}
251+
if !config.Opts.DisableAPI() {
252+
api.Serve(subrouter, store, pool)
253+
}
248254
ui.Serve(subrouter, store, pool)
249255

250256
subrouter.HandleFunc("/healthcheck", readinessProbe).Name("healthcheck")

miniflux.1

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,21 @@ Path to a secret key exposed as a file, it should contain $DATABASE_URL value\&.
235235
.br
236236
Default is empty\&.
237237
.TP
238+
.B DISABLE_API
239+
Disable miniflux' API\&.
240+
.br
241+
Default is false (The API is enabled)\&.
242+
.TP
243+
.B DISABLE_FEVER_API
244+
Disable the Fever API\&.
245+
.br
246+
Default is false (The Fever API is enabled)\&.
247+
.TP
248+
.B DISABLE_GOOGLEREADER_API
249+
Disable the Google Reader API\&.
250+
.br
251+
Default is false (The Google Reader API is enabled)\&.
252+
.TP
238253
.B DISABLE_HSTS
239254
Disable HTTP Strict Transport Security header if \fBHTTPS\fR is set\&.
240255
.br

0 commit comments

Comments
 (0)