options.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. // Copyright 2019 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package config // import "miniflux.app/config"
  5. import (
  6. "fmt"
  7. "sort"
  8. "strings"
  9. "miniflux.app/version"
  10. )
  11. const (
  12. defaultHTTPS = false
  13. defaultLogDateTime = false
  14. defaultHSTS = true
  15. defaultHTTPService = true
  16. defaultSchedulerService = true
  17. defaultDebug = false
  18. defaultTiming = false
  19. defaultBaseURL = "http://localhost"
  20. defaultRootURL = "http://localhost"
  21. defaultBasePath = ""
  22. defaultWorkerPoolSize = 5
  23. defaultPollingFrequency = 60
  24. defaultBatchSize = 10
  25. defaultPollingScheduler = "round_robin"
  26. defaultSchedulerEntryFrequencyMinInterval = 5
  27. defaultSchedulerEntryFrequencyMaxInterval = 24 * 60
  28. defaultPollingParsingErrorLimit = 3
  29. defaultRunMigrations = false
  30. defaultDatabaseURL = "user=postgres password=postgres dbname=miniflux2 sslmode=disable"
  31. defaultDatabaseMaxConns = 20
  32. defaultDatabaseMinConns = 1
  33. defaultListenAddr = "127.0.0.1:8080"
  34. defaultCertFile = ""
  35. defaultKeyFile = ""
  36. defaultCertDomain = ""
  37. defaultCleanupFrequencyHours = 24
  38. defaultCleanupArchiveReadDays = 60
  39. defaultCleanupArchiveUnreadDays = 180
  40. defaultCleanupRemoveSessionsDays = 30
  41. defaultProxyImages = "http-only"
  42. defaultFetchYouTubeWatchTime = false
  43. defaultCreateAdmin = false
  44. defaultAdminUsername = ""
  45. defaultAdminPassword = ""
  46. defaultOAuth2UserCreation = false
  47. defaultOAuth2ClientID = ""
  48. defaultOAuth2ClientSecret = ""
  49. defaultOAuth2RedirectURL = ""
  50. defaultOAuth2OidcDiscoveryEndpoint = ""
  51. defaultOAuth2Provider = ""
  52. defaultPocketConsumerKey = ""
  53. defaultHTTPClientTimeout = 20
  54. defaultHTTPClientMaxBodySize = 15
  55. defaultHTTPClientProxy = ""
  56. defaultAuthProxyHeader = ""
  57. defaultAuthProxyUserCreation = false
  58. defaultMaintenanceMode = false
  59. defaultMaintenanceMessage = "Miniflux is currently under maintenance"
  60. defaultMetricsCollector = false
  61. defaultMetricsRefreshInterval = 60
  62. defaultMetricsAllowedNetworks = "127.0.0.1/8"
  63. )
  64. var defaultHTTPClientUserAgent = "Mozilla/5.0 (compatible; Miniflux/" + version.Version + "; +https://miniflux.app)"
  65. // Option contains a key to value map of a single option. It may be used to output debug strings.
  66. type Option struct {
  67. Key string
  68. Value interface{}
  69. }
  70. // Options contains configuration options.
  71. type Options struct {
  72. HTTPS bool
  73. logDateTime bool
  74. hsts bool
  75. httpService bool
  76. schedulerService bool
  77. debug bool
  78. serverTimingHeader bool
  79. baseURL string
  80. rootURL string
  81. basePath string
  82. databaseURL string
  83. databaseMaxConns int
  84. databaseMinConns int
  85. runMigrations bool
  86. listenAddr string
  87. certFile string
  88. certDomain string
  89. certKeyFile string
  90. cleanupFrequencyHours int
  91. cleanupArchiveReadDays int
  92. cleanupArchiveUnreadDays int
  93. cleanupRemoveSessionsDays int
  94. pollingFrequency int
  95. batchSize int
  96. pollingScheduler string
  97. schedulerEntryFrequencyMinInterval int
  98. schedulerEntryFrequencyMaxInterval int
  99. pollingParsingErrorLimit int
  100. workerPoolSize int
  101. createAdmin bool
  102. adminUsername string
  103. adminPassword string
  104. proxyImages string
  105. fetchYouTubeWatchTime bool
  106. oauth2UserCreationAllowed bool
  107. oauth2ClientID string
  108. oauth2ClientSecret string
  109. oauth2RedirectURL string
  110. oauth2OidcDiscoveryEndpoint string
  111. oauth2Provider string
  112. pocketConsumerKey string
  113. httpClientTimeout int
  114. httpClientMaxBodySize int64
  115. httpClientProxy string
  116. httpClientUserAgent string
  117. authProxyHeader string
  118. authProxyUserCreation bool
  119. maintenanceMode bool
  120. maintenanceMessage string
  121. metricsCollector bool
  122. metricsRefreshInterval int
  123. metricsAllowedNetworks []string
  124. }
  125. // NewOptions returns Options with default values.
  126. func NewOptions() *Options {
  127. return &Options{
  128. HTTPS: defaultHTTPS,
  129. logDateTime: defaultLogDateTime,
  130. hsts: defaultHSTS,
  131. httpService: defaultHTTPService,
  132. schedulerService: defaultSchedulerService,
  133. debug: defaultDebug,
  134. serverTimingHeader: defaultTiming,
  135. baseURL: defaultBaseURL,
  136. rootURL: defaultRootURL,
  137. basePath: defaultBasePath,
  138. databaseURL: defaultDatabaseURL,
  139. databaseMaxConns: defaultDatabaseMaxConns,
  140. databaseMinConns: defaultDatabaseMinConns,
  141. runMigrations: defaultRunMigrations,
  142. listenAddr: defaultListenAddr,
  143. certFile: defaultCertFile,
  144. certDomain: defaultCertDomain,
  145. certKeyFile: defaultKeyFile,
  146. cleanupFrequencyHours: defaultCleanupFrequencyHours,
  147. cleanupArchiveReadDays: defaultCleanupArchiveReadDays,
  148. cleanupArchiveUnreadDays: defaultCleanupArchiveUnreadDays,
  149. cleanupRemoveSessionsDays: defaultCleanupRemoveSessionsDays,
  150. pollingFrequency: defaultPollingFrequency,
  151. batchSize: defaultBatchSize,
  152. pollingScheduler: defaultPollingScheduler,
  153. schedulerEntryFrequencyMinInterval: defaultSchedulerEntryFrequencyMinInterval,
  154. schedulerEntryFrequencyMaxInterval: defaultSchedulerEntryFrequencyMaxInterval,
  155. pollingParsingErrorLimit: defaultPollingParsingErrorLimit,
  156. workerPoolSize: defaultWorkerPoolSize,
  157. createAdmin: defaultCreateAdmin,
  158. proxyImages: defaultProxyImages,
  159. fetchYouTubeWatchTime: defaultFetchYouTubeWatchTime,
  160. oauth2UserCreationAllowed: defaultOAuth2UserCreation,
  161. oauth2ClientID: defaultOAuth2ClientID,
  162. oauth2ClientSecret: defaultOAuth2ClientSecret,
  163. oauth2RedirectURL: defaultOAuth2RedirectURL,
  164. oauth2OidcDiscoveryEndpoint: defaultOAuth2OidcDiscoveryEndpoint,
  165. oauth2Provider: defaultOAuth2Provider,
  166. pocketConsumerKey: defaultPocketConsumerKey,
  167. httpClientTimeout: defaultHTTPClientTimeout,
  168. httpClientMaxBodySize: defaultHTTPClientMaxBodySize * 1024 * 1024,
  169. httpClientProxy: defaultHTTPClientProxy,
  170. httpClientUserAgent: defaultHTTPClientUserAgent,
  171. authProxyHeader: defaultAuthProxyHeader,
  172. authProxyUserCreation: defaultAuthProxyUserCreation,
  173. maintenanceMode: defaultMaintenanceMode,
  174. maintenanceMessage: defaultMaintenanceMessage,
  175. metricsCollector: defaultMetricsCollector,
  176. metricsRefreshInterval: defaultMetricsRefreshInterval,
  177. metricsAllowedNetworks: []string{defaultMetricsAllowedNetworks},
  178. }
  179. }
  180. // LogDateTime returns true if the date/time should be displayed in log messages.
  181. func (o *Options) LogDateTime() bool {
  182. return o.logDateTime
  183. }
  184. // HasMaintenanceMode returns true if maintenance mode is enabled.
  185. func (o *Options) HasMaintenanceMode() bool {
  186. return o.maintenanceMode
  187. }
  188. // MaintenanceMessage returns maintenance message.
  189. func (o *Options) MaintenanceMessage() string {
  190. return o.maintenanceMessage
  191. }
  192. // HasDebugMode returns true if debug mode is enabled.
  193. func (o *Options) HasDebugMode() bool {
  194. return o.debug
  195. }
  196. // HasServerTimingHeader returns true if server-timing headers enabled.
  197. func (o *Options) HasServerTimingHeader() bool {
  198. return o.serverTimingHeader
  199. }
  200. // BaseURL returns the application base URL with path.
  201. func (o *Options) BaseURL() string {
  202. return o.baseURL
  203. }
  204. // RootURL returns the base URL without path.
  205. func (o *Options) RootURL() string {
  206. return o.rootURL
  207. }
  208. // BasePath returns the application base path according to the base URL.
  209. func (o *Options) BasePath() string {
  210. return o.basePath
  211. }
  212. // IsDefaultDatabaseURL returns true if the default database URL is used.
  213. func (o *Options) IsDefaultDatabaseURL() bool {
  214. return o.databaseURL == defaultDatabaseURL
  215. }
  216. // DatabaseURL returns the database URL.
  217. func (o *Options) DatabaseURL() string {
  218. return o.databaseURL
  219. }
  220. // DatabaseMaxConns returns the maximum number of database connections.
  221. func (o *Options) DatabaseMaxConns() int {
  222. return o.databaseMaxConns
  223. }
  224. // DatabaseMinConns returns the minimum number of database connections.
  225. func (o *Options) DatabaseMinConns() int {
  226. return o.databaseMinConns
  227. }
  228. // ListenAddr returns the listen address for the HTTP server.
  229. func (o *Options) ListenAddr() string {
  230. return o.listenAddr
  231. }
  232. // CertFile returns the SSL certificate filename if any.
  233. func (o *Options) CertFile() string {
  234. return o.certFile
  235. }
  236. // CertKeyFile returns the private key filename for custom SSL certificate.
  237. func (o *Options) CertKeyFile() string {
  238. return o.certKeyFile
  239. }
  240. // CertDomain returns the domain to use for Let's Encrypt certificate.
  241. func (o *Options) CertDomain() string {
  242. return o.certDomain
  243. }
  244. // CleanupFrequencyHours returns the interval in hours for cleanup jobs.
  245. func (o *Options) CleanupFrequencyHours() int {
  246. return o.cleanupFrequencyHours
  247. }
  248. // CleanupArchiveReadDays returns the number of days after which marking read items as removed.
  249. func (o *Options) CleanupArchiveReadDays() int {
  250. return o.cleanupArchiveReadDays
  251. }
  252. // CleanupArchiveUnreadDays returns the number of days after which marking unread items as removed.
  253. func (o *Options) CleanupArchiveUnreadDays() int {
  254. return o.cleanupArchiveUnreadDays
  255. }
  256. // CleanupRemoveSessionsDays returns the number of days after which to remove sessions.
  257. func (o *Options) CleanupRemoveSessionsDays() int {
  258. return o.cleanupRemoveSessionsDays
  259. }
  260. // WorkerPoolSize returns the number of background worker.
  261. func (o *Options) WorkerPoolSize() int {
  262. return o.workerPoolSize
  263. }
  264. // PollingFrequency returns the interval to refresh feeds in the background.
  265. func (o *Options) PollingFrequency() int {
  266. return o.pollingFrequency
  267. }
  268. // BatchSize returns the number of feeds to send for background processing.
  269. func (o *Options) BatchSize() int {
  270. return o.batchSize
  271. }
  272. // PollingScheduler returns the scheduler used for polling feeds.
  273. func (o *Options) PollingScheduler() string {
  274. return o.pollingScheduler
  275. }
  276. // SchedulerEntryFrequencyMaxInterval returns the maximum interval in minutes for the entry frequency scheduler.
  277. func (o *Options) SchedulerEntryFrequencyMaxInterval() int {
  278. return o.schedulerEntryFrequencyMaxInterval
  279. }
  280. // SchedulerEntryFrequencyMinInterval returns the minimum interval in minutes for the entry frequency scheduler.
  281. func (o *Options) SchedulerEntryFrequencyMinInterval() int {
  282. return o.schedulerEntryFrequencyMinInterval
  283. }
  284. // PollingParsingErrorLimit returns the limit of errors when to stop polling.
  285. func (o *Options) PollingParsingErrorLimit() int {
  286. return o.pollingParsingErrorLimit
  287. }
  288. // IsOAuth2UserCreationAllowed returns true if user creation is allowed for OAuth2 users.
  289. func (o *Options) IsOAuth2UserCreationAllowed() bool {
  290. return o.oauth2UserCreationAllowed
  291. }
  292. // OAuth2ClientID returns the OAuth2 Client ID.
  293. func (o *Options) OAuth2ClientID() string {
  294. return o.oauth2ClientID
  295. }
  296. // OAuth2ClientSecret returns the OAuth2 client secret.
  297. func (o *Options) OAuth2ClientSecret() string {
  298. return o.oauth2ClientSecret
  299. }
  300. // OAuth2RedirectURL returns the OAuth2 redirect URL.
  301. func (o *Options) OAuth2RedirectURL() string {
  302. return o.oauth2RedirectURL
  303. }
  304. // OAuth2OidcDiscoveryEndpoint returns the OAuth2 OIDC discovery endpoint.
  305. func (o *Options) OAuth2OidcDiscoveryEndpoint() string {
  306. return o.oauth2OidcDiscoveryEndpoint
  307. }
  308. // OAuth2Provider returns the name of the OAuth2 provider configured.
  309. func (o *Options) OAuth2Provider() string {
  310. return o.oauth2Provider
  311. }
  312. // HasHSTS returns true if HTTP Strict Transport Security is enabled.
  313. func (o *Options) HasHSTS() bool {
  314. return o.hsts
  315. }
  316. // RunMigrations returns true if the environment variable RUN_MIGRATIONS is not empty.
  317. func (o *Options) RunMigrations() bool {
  318. return o.runMigrations
  319. }
  320. // CreateAdmin returns true if the environment variable CREATE_ADMIN is not empty.
  321. func (o *Options) CreateAdmin() bool {
  322. return o.createAdmin
  323. }
  324. // AdminUsername returns the admin username if defined.
  325. func (o *Options) AdminUsername() string {
  326. return o.adminUsername
  327. }
  328. // AdminPassword returns the admin password if defined.
  329. func (o *Options) AdminPassword() string {
  330. return o.adminPassword
  331. }
  332. // FetchYouTubeWatchTime returns true if the YouTube video duration
  333. // should be fetched and used as a reading time.
  334. func (o *Options) FetchYouTubeWatchTime() bool {
  335. return o.fetchYouTubeWatchTime
  336. }
  337. // ProxyImages returns "none" to never proxy, "http-only" to proxy non-HTTPS, "all" to always proxy.
  338. func (o *Options) ProxyImages() string {
  339. return o.proxyImages
  340. }
  341. // HasHTTPService returns true if the HTTP service is enabled.
  342. func (o *Options) HasHTTPService() bool {
  343. return o.httpService
  344. }
  345. // HasSchedulerService returns true if the scheduler service is enabled.
  346. func (o *Options) HasSchedulerService() bool {
  347. return o.schedulerService
  348. }
  349. // PocketConsumerKey returns the Pocket Consumer Key if configured.
  350. func (o *Options) PocketConsumerKey(defaultValue string) string {
  351. if o.pocketConsumerKey != "" {
  352. return o.pocketConsumerKey
  353. }
  354. return defaultValue
  355. }
  356. // HTTPClientTimeout returns the time limit in seconds before the HTTP client cancel the request.
  357. func (o *Options) HTTPClientTimeout() int {
  358. return o.httpClientTimeout
  359. }
  360. // HTTPClientMaxBodySize returns the number of bytes allowed for the HTTP client to transfer.
  361. func (o *Options) HTTPClientMaxBodySize() int64 {
  362. return o.httpClientMaxBodySize
  363. }
  364. // HTTPClientProxy returns the proxy URL for HTTP client.
  365. func (o *Options) HTTPClientProxy() string {
  366. return o.httpClientProxy
  367. }
  368. // HasHTTPClientProxyConfigured returns true if the HTTP proxy is configured.
  369. func (o *Options) HasHTTPClientProxyConfigured() bool {
  370. return o.httpClientProxy != ""
  371. }
  372. // AuthProxyHeader returns an HTTP header name that contains username for
  373. // authentication using auth proxy.
  374. func (o *Options) AuthProxyHeader() string {
  375. return o.authProxyHeader
  376. }
  377. // IsAuthProxyUserCreationAllowed returns true if user creation is allowed for
  378. // users authenticated using auth proxy.
  379. func (o *Options) IsAuthProxyUserCreationAllowed() bool {
  380. return o.authProxyUserCreation
  381. }
  382. // HasMetricsCollector returns true if metrics collection is enabled.
  383. func (o *Options) HasMetricsCollector() bool {
  384. return o.metricsCollector
  385. }
  386. // MetricsRefreshInterval returns the refresh interval in seconds.
  387. func (o *Options) MetricsRefreshInterval() int {
  388. return o.metricsRefreshInterval
  389. }
  390. // MetricsAllowedNetworks returns the list of networks allowed to connect to the metrics endpoint.
  391. func (o *Options) MetricsAllowedNetworks() []string {
  392. return o.metricsAllowedNetworks
  393. }
  394. // HTTPClientUserAgent returns the global User-Agent header for miniflux.
  395. func (o *Options) HTTPClientUserAgent() string {
  396. return o.httpClientUserAgent
  397. }
  398. // SortedOptions returns options as a list of key value pairs, sorted by keys.
  399. func (o *Options) SortedOptions() []*Option {
  400. var keyValues = map[string]interface{}{
  401. "ADMIN_PASSWORD": o.adminPassword,
  402. "ADMIN_USERNAME": o.adminUsername,
  403. "AUTH_PROXY_HEADER": o.authProxyHeader,
  404. "AUTH_PROXY_USER_CREATION": o.authProxyUserCreation,
  405. "BASE_PATH": o.basePath,
  406. "BASE_URL": o.baseURL,
  407. "BATCH_SIZE": o.batchSize,
  408. "CERT_DOMAIN": o.certDomain,
  409. "CERT_FILE": o.certFile,
  410. "CLEANUP_ARCHIVE_READ_DAYS": o.cleanupArchiveReadDays,
  411. "CLEANUP_ARCHIVE_UNREAD_DAYS": o.cleanupArchiveUnreadDays,
  412. "CLEANUP_FREQUENCY_HOURS": o.cleanupFrequencyHours,
  413. "CLEANUP_REMOVE_SESSIONS_DAYS": o.cleanupRemoveSessionsDays,
  414. "CREATE_ADMIN": o.createAdmin,
  415. "DATABASE_MAX_CONNS": o.databaseMaxConns,
  416. "DATABASE_MIN_CONNS": o.databaseMinConns,
  417. "DATABASE_URL": o.databaseURL,
  418. "DEBUG": o.debug,
  419. "FETCH_YOUTUBE_WATCH_TIME": o.fetchYouTubeWatchTime,
  420. "HSTS": o.hsts,
  421. "HTTPS": o.HTTPS,
  422. "HTTP_CLIENT_MAX_BODY_SIZE": o.httpClientMaxBodySize,
  423. "HTTP_CLIENT_PROXY": o.httpClientProxy,
  424. "HTTP_CLIENT_TIMEOUT": o.httpClientTimeout,
  425. "HTTP_CLIENT_USER_AGENT": o.httpClientUserAgent,
  426. "HTTP_SERVICE": o.httpService,
  427. "KEY_FILE": o.certKeyFile,
  428. "LISTEN_ADDR": o.listenAddr,
  429. "LOG_DATE_TIME": o.logDateTime,
  430. "MAINTENANCE_MESSAGE": o.maintenanceMessage,
  431. "MAINTENANCE_MODE": o.maintenanceMode,
  432. "METRICS_ALLOWED_NETWORKS": o.metricsAllowedNetworks,
  433. "METRICS_COLLECTOR": o.metricsCollector,
  434. "METRICS_REFRESH_INTERVAL": o.metricsRefreshInterval,
  435. "OAUTH2_CLIENT_ID": o.oauth2ClientID,
  436. "OAUTH2_CLIENT_SECRET": o.oauth2ClientSecret,
  437. "OAUTH2_OIDC_DISCOVERY_ENDPOINT": o.oauth2OidcDiscoveryEndpoint,
  438. "OAUTH2_PROVIDER": o.oauth2Provider,
  439. "OAUTH2_REDIRECT_URL": o.oauth2RedirectURL,
  440. "OAUTH2_USER_CREATION": o.oauth2UserCreationAllowed,
  441. "POCKET_CONSUMER_KEY": o.pocketConsumerKey,
  442. "POLLING_FREQUENCY": o.pollingFrequency,
  443. "POLLING_PARSING_ERROR_LIMIT": o.pollingParsingErrorLimit,
  444. "POLLING_SCHEDULER": o.pollingScheduler,
  445. "PROXY_IMAGES": o.proxyImages,
  446. "ROOT_URL": o.rootURL,
  447. "RUN_MIGRATIONS": o.runMigrations,
  448. "SCHEDULER_ENTRY_FREQUENCY_MAX_INTERVAL": o.schedulerEntryFrequencyMaxInterval,
  449. "SCHEDULER_ENTRY_FREQUENCY_MIN_INTERVAL": o.schedulerEntryFrequencyMinInterval,
  450. "SCHEDULER_SERVICE": o.schedulerService,
  451. "SERVER_TIMING_HEADER": o.serverTimingHeader,
  452. "WORKER_POOL_SIZE": o.workerPoolSize,
  453. }
  454. keys := make([]string, 0, len(keyValues))
  455. for key := range keyValues {
  456. keys = append(keys, key)
  457. }
  458. sort.Strings(keys)
  459. var sortedOptions []*Option
  460. for _, key := range keys {
  461. sortedOptions = append(sortedOptions, &Option{Key: key, Value: keyValues[key]})
  462. }
  463. return sortedOptions
  464. }
  465. func (o *Options) String() string {
  466. var builder strings.Builder
  467. for _, option := range o.SortedOptions() {
  468. builder.WriteString(fmt.Sprintf("%s: %v\n", option.Key, option.Value))
  469. }
  470. return builder.String()
  471. }