A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

169 lines
4.1 KiB

  1. /*
  2. * Copyright © 2018-2019 A Bunch Tell LLC.
  3. *
  4. * This file is part of WriteFreely.
  5. *
  6. * WriteFreely is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License, included
  8. * in the LICENSE file in this source code package.
  9. */
  10. // Package config holds and assists in the configuration of a writefreely instance.
  11. package config
  12. import (
  13. "gopkg.in/ini.v1"
  14. )
  15. const (
  16. // FileName is the default configuration file name
  17. FileName = "config.ini"
  18. UserNormal UserType = "user"
  19. UserAdmin = "admin"
  20. )
  21. type (
  22. UserType string
  23. // ServerCfg holds values that affect how the HTTP server runs
  24. ServerCfg struct {
  25. HiddenHost string `ini:"hidden_host"`
  26. Port int `ini:"port"`
  27. Bind string `ini:"bind"`
  28. TLSCertPath string `ini:"tls_cert_path"`
  29. TLSKeyPath string `ini:"tls_key_path"`
  30. TemplatesParentDir string `ini:"templates_parent_dir"`
  31. StaticParentDir string `ini:"static_parent_dir"`
  32. PagesParentDir string `ini:"pages_parent_dir"`
  33. KeysParentDir string `ini:"keys_parent_dir"`
  34. Dev bool `ini:"-"`
  35. }
  36. // DatabaseCfg holds values that determine how the application connects to a datastore
  37. DatabaseCfg struct {
  38. Type string `ini:"type"`
  39. FileName string `ini:"filename"`
  40. User string `ini:"username"`
  41. Password string `ini:"password"`
  42. Database string `ini:"database"`
  43. Host string `ini:"host"`
  44. Port int `ini:"port"`
  45. }
  46. // AppCfg holds values that affect how the application functions
  47. AppCfg struct {
  48. SiteName string `ini:"site_name"`
  49. SiteDesc string `ini:"site_description"`
  50. Host string `ini:"host"`
  51. // Site appearance
  52. Theme string `ini:"theme"`
  53. JSDisabled bool `ini:"disable_js"`
  54. WebFonts bool `ini:"webfonts"`
  55. // Users
  56. SingleUser bool `ini:"single_user"`
  57. OpenRegistration bool `ini:"open_registration"`
  58. MinUsernameLen int `ini:"min_username_len"`
  59. MaxBlogs int `ini:"max_blogs"`
  60. // Federation
  61. Federation bool `ini:"federation"`
  62. PublicStats bool `ini:"public_stats"`
  63. Private bool `ini:"private"`
  64. // Additional functions
  65. LocalTimeline bool `ini:"local_timeline"`
  66. UserInvites string `ini:"user_invites"`
  67. }
  68. // Config holds the complete configuration for running a writefreely instance
  69. Config struct {
  70. Server ServerCfg `ini:"server"`
  71. Database DatabaseCfg `ini:"database"`
  72. App AppCfg `ini:"app"`
  73. }
  74. )
  75. // New creates a new Config with sane defaults
  76. func New() *Config {
  77. c := &Config{
  78. Server: ServerCfg{
  79. Port: 8080,
  80. Bind: "localhost", /* IPV6 support when not using localhost? */
  81. },
  82. App: AppCfg{
  83. Host: "http://localhost:8080",
  84. Theme: "write",
  85. WebFonts: true,
  86. SingleUser: true,
  87. MinUsernameLen: 3,
  88. MaxBlogs: 1,
  89. Federation: true,
  90. PublicStats: true,
  91. },
  92. }
  93. c.UseMySQL(true)
  94. return c
  95. }
  96. // UseMySQL resets the Config's Database to use default values for a MySQL setup.
  97. func (cfg *Config) UseMySQL(fresh bool) {
  98. cfg.Database.Type = "mysql"
  99. if fresh {
  100. cfg.Database.Host = "localhost"
  101. cfg.Database.Port = 3306
  102. }
  103. }
  104. // UseSQLite resets the Config's Database to use default values for a SQLite setup.
  105. func (cfg *Config) UseSQLite(fresh bool) {
  106. cfg.Database.Type = "sqlite3"
  107. if fresh {
  108. cfg.Database.FileName = "writefreely.db"
  109. }
  110. }
  111. // IsSecureStandalone returns whether or not the application is running as a
  112. // standalone server with TLS enabled.
  113. func (cfg *Config) IsSecureStandalone() bool {
  114. return cfg.Server.Port == 443 && cfg.Server.TLSCertPath != "" && cfg.Server.TLSKeyPath != ""
  115. }
  116. // Load reads the given configuration file, then parses and returns it as a Config.
  117. func Load(fname string) (*Config, error) {
  118. if fname == "" {
  119. fname = FileName
  120. }
  121. cfg, err := ini.Load(fname)
  122. if err != nil {
  123. return nil, err
  124. }
  125. // Parse INI file
  126. uc := &Config{}
  127. err = cfg.MapTo(uc)
  128. if err != nil {
  129. return nil, err
  130. }
  131. return uc, nil
  132. }
  133. // Save writes the given Config to the given file.
  134. func Save(uc *Config, fname string) error {
  135. cfg := ini.Empty()
  136. err := ini.ReflectFrom(cfg, uc)
  137. if err != nil {
  138. return err
  139. }
  140. if fname == "" {
  141. fname = FileName
  142. }
  143. return cfg.SaveTo(fname)
  144. }