generator.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. package appservice
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "regexp"
  7. "strconv"
  8. "strings"
  9. "github.com/fatih/color"
  10. )
  11. func readString(reader *bufio.Reader, message, defaultValue string) (string, error) {
  12. color.Green(message)
  13. if len(defaultValue) > 0 {
  14. fmt.Printf("[%s]", defaultValue)
  15. }
  16. fmt.Print("> ")
  17. val, err := reader.ReadString('\n')
  18. if err != nil {
  19. return "", err
  20. }
  21. val = strings.TrimSuffix(val, "\n")
  22. if len(val) == 0 {
  23. return defaultValue, nil
  24. }
  25. val = strings.TrimSuffix(val, "\r")
  26. if len(val) == 0 {
  27. return defaultValue, nil
  28. }
  29. return val, nil
  30. }
  31. const (
  32. yes = "yes"
  33. yesShort = "y"
  34. )
  35. // GenerateRegistration asks the user questions and generates a config and registration based on the answers.
  36. func GenerateRegistration(asName, botName string, reserveRooms, reserveUsers bool) {
  37. var boldCyan = color.New(color.FgCyan).Add(color.Bold)
  38. var boldGreen = color.New(color.FgGreen).Add(color.Bold)
  39. boldCyan.Println("Generating appservice config and registration.")
  40. reader := bufio.NewReader(os.Stdin)
  41. registration := CreateRegistration()
  42. config := Create()
  43. registration.RateLimited = false
  44. name, err := readString(reader, "Enter name for appservice", asName)
  45. if err != nil {
  46. fmt.Println("Failed to read user Input:", err)
  47. return
  48. }
  49. registration.ID = name
  50. registration.SenderLocalpart, err = readString(reader, "Enter bot username", botName)
  51. if err != nil {
  52. fmt.Println("Failed to read user Input:", err)
  53. return
  54. }
  55. asProtocol, err := readString(reader, "Enter appservice host protocol", "http")
  56. if err != nil {
  57. fmt.Println("Failed to read user Input:", err)
  58. return
  59. }
  60. if asProtocol == "https" {
  61. sslInput, err := readString(reader, "Do you want the appservice to handle SSL [yes/no]?", "yes")
  62. if err != nil {
  63. fmt.Println("Failed to read user Input:", err)
  64. return
  65. }
  66. wantSSL := strings.ToLower(sslInput)
  67. if wantSSL == yes {
  68. config.Host.TLSCert, err = readString(reader, "Enter path to SSL certificate", "appservice.crt")
  69. if err != nil {
  70. fmt.Println("Failed to read user Input:", err)
  71. return
  72. }
  73. config.Host.TLSKey, err = readString(reader, "Enter path to SSL key", "appservice.key")
  74. if err != nil {
  75. fmt.Println("Failed to read user Input:", err)
  76. return
  77. }
  78. }
  79. }
  80. asHostname, err := readString(reader, "Enter appservice hostname", "localhost")
  81. if err != nil {
  82. fmt.Println("Failed to read user Input:", err)
  83. return
  84. }
  85. asInput, err := readString(reader, "Enter appservice host port", "29313")
  86. if err != nil {
  87. fmt.Println("Failed to read user Input:", err)
  88. return
  89. }
  90. asPort, convErr := strconv.Atoi(asInput)
  91. if convErr != nil {
  92. fmt.Println("Failed to parse port:", convErr)
  93. return
  94. }
  95. registration.URL = fmt.Sprintf("%s://%s:%d", asProtocol, asHostname, asPort)
  96. config.Host.Hostname = asHostname
  97. config.Host.Port = uint16(asPort)
  98. config.HomeserverURL, err = readString(reader, "Enter homeserver address", "http://localhost:8008")
  99. if err != nil {
  100. fmt.Println("Failed to read user Input:", err)
  101. return
  102. }
  103. config.HomeserverDomain, err = readString(reader, "Enter homeserver domain", "example.com")
  104. if err != nil {
  105. fmt.Println("Failed to read user Input:", err)
  106. return
  107. }
  108. config.LogConfig.Directory, err = readString(reader, "Enter directory for logs", "./logs")
  109. if err != nil {
  110. fmt.Println("Failed to read user Input:", err)
  111. return
  112. }
  113. os.MkdirAll(config.LogConfig.Directory, 0755)
  114. if reserveRooms || reserveUsers {
  115. for {
  116. namespace, err := readString(reader, "Enter namespace prefix", fmt.Sprintf("_%s_", name))
  117. if err != nil {
  118. fmt.Println("Failed to read user Input:", err)
  119. return
  120. }
  121. roomNamespaceRegex, err := regexp.Compile(fmt.Sprintf("#%s.+:%s", namespace, config.HomeserverDomain))
  122. if err != nil {
  123. fmt.Println(err)
  124. continue
  125. }
  126. userNamespaceRegex, regexpErr := regexp.Compile(fmt.Sprintf("@%s.+:%s", namespace, config.HomeserverDomain))
  127. if regexpErr != nil {
  128. fmt.Println("Failed to generate regexp for the userNamespace:", err)
  129. return
  130. }
  131. if reserveRooms {
  132. registration.Namespaces.RegisterRoomAliases(roomNamespaceRegex, true)
  133. }
  134. if reserveUsers {
  135. registration.Namespaces.RegisterUserIDs(userNamespaceRegex, true)
  136. }
  137. break
  138. }
  139. }
  140. boldCyan.Println("\n==== Registration generated ====")
  141. yamlString, yamlErr := registration.YAML()
  142. if err != nil {
  143. fmt.Println("Failed to return the registration Config:", yamlErr)
  144. return
  145. }
  146. color.Yellow(yamlString)
  147. okInput, readErr := readString(reader, "Does the registration look OK [yes/no]?", "yes")
  148. if readErr != nil {
  149. fmt.Println("Failed to read user Input:", readErr)
  150. return
  151. }
  152. ok := strings.ToLower(okInput)
  153. if ok != yesShort && ok != yes {
  154. fmt.Println("Cancelling generation.")
  155. return
  156. }
  157. path, err := readString(reader, "Where should the registration be saved?", "registration.yaml")
  158. if err != nil {
  159. fmt.Println("Failed to read user Input:", err)
  160. return
  161. }
  162. err = registration.Save(path)
  163. if err != nil {
  164. fmt.Println("Failed to save registration:", err)
  165. return
  166. }
  167. boldGreen.Println("Registration saved.")
  168. config.RegistrationPath = path
  169. boldCyan.Println("\n======= Config generated =======")
  170. color.Yellow(config.YAML())
  171. okString, err := readString(reader, "Does the config look OK [yes/no]?", "yes")
  172. if err != nil {
  173. fmt.Println("Failed to read user Input:", err)
  174. return
  175. }
  176. ok = strings.ToLower(okString)
  177. if ok != yesShort && ok != yes {
  178. fmt.Println("Cancelling generation.")
  179. return
  180. }
  181. path, err = readString(reader, "Where should the config be saved?", "config.yaml")
  182. if err != nil {
  183. fmt.Println("Failed to read user Input:", err)
  184. return
  185. }
  186. err = config.Save(path)
  187. if err != nil {
  188. fmt.Println("Failed to save config:", err)
  189. return
  190. }
  191. boldGreen.Println("Config saved.")
  192. }