generator.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  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. name, err := readString(reader, "Enter name for appservice", asName)
  42. if err != nil {
  43. fmt.Println("Failed to read user Input:", err)
  44. return
  45. }
  46. registration := CreateRegistration(name)
  47. config := Create()
  48. registration.RateLimited = false
  49. registration.SenderLocalpart, err = readString(reader, "Enter bot username", botName)
  50. if err != nil {
  51. fmt.Println("Failed to read user Input:", err)
  52. return
  53. }
  54. asProtocol, err := readString(reader, "Enter appservice host protocol", "http")
  55. if err != nil {
  56. fmt.Println("Failed to read user Input:", err)
  57. return
  58. }
  59. if asProtocol == "https" {
  60. sslInput, err := readString(reader, "Do you want the appservice to handle SSL [yes/no]?", "yes")
  61. if err != nil {
  62. fmt.Println("Failed to read user Input:", err)
  63. return
  64. }
  65. wantSSL := strings.ToLower(sslInput)
  66. if wantSSL == yes {
  67. config.Host.TLSCert, err = readString(reader, "Enter path to SSL certificate", "appservice.crt")
  68. if err != nil {
  69. fmt.Println("Failed to read user Input:", err)
  70. return
  71. }
  72. config.Host.TLSKey, err = readString(reader, "Enter path to SSL key", "appservice.key")
  73. if err != nil {
  74. fmt.Println("Failed to read user Input:", err)
  75. return
  76. }
  77. }
  78. }
  79. asHostname, err := readString(reader, "Enter appservice hostname", "localhost")
  80. if err != nil {
  81. fmt.Println("Failed to read user Input:", err)
  82. return
  83. }
  84. asInput, err := readString(reader, "Enter appservice host port", "29313")
  85. if err != nil {
  86. fmt.Println("Failed to read user Input:", err)
  87. return
  88. }
  89. asPort, convErr := strconv.Atoi(asInput)
  90. if convErr != nil {
  91. fmt.Println("Failed to parse port:", convErr)
  92. return
  93. }
  94. registration.URL = fmt.Sprintf("%s://%s:%d", asProtocol, asHostname, asPort)
  95. config.Host.Hostname = asHostname
  96. config.Host.Port = uint16(asPort)
  97. config.HomeserverURL, err = readString(reader, "Enter homeserver address", "http://localhost:8008")
  98. if err != nil {
  99. fmt.Println("Failed to read user Input:", err)
  100. return
  101. }
  102. config.HomeserverDomain, err = readString(reader, "Enter homeserver domain", "example.com")
  103. if err != nil {
  104. fmt.Println("Failed to read user Input:", err)
  105. return
  106. }
  107. config.LogConfig.Directory, err = readString(reader, "Enter directory for logs", "./logs")
  108. if err != nil {
  109. fmt.Println("Failed to read user Input:", err)
  110. return
  111. }
  112. os.MkdirAll(config.LogConfig.Directory, 0755)
  113. if reserveRooms || reserveUsers {
  114. for {
  115. namespace, err := readString(reader, "Enter namespace prefix", fmt.Sprintf("_%s_", name))
  116. if err != nil {
  117. fmt.Println("Failed to read user Input:", err)
  118. return
  119. }
  120. roomNamespaceRegex, err := regexp.Compile(fmt.Sprintf("#%s.+:%s", namespace, config.HomeserverDomain))
  121. if err != nil {
  122. fmt.Println(err)
  123. continue
  124. }
  125. userNamespaceRegex, regexpErr := regexp.Compile(fmt.Sprintf("@%s.+:%s", namespace, config.HomeserverDomain))
  126. if regexpErr != nil {
  127. fmt.Println("Failed to generate regexp for the userNamespace:", err)
  128. return
  129. }
  130. if reserveRooms {
  131. registration.Namespaces.RegisterRoomAliases(roomNamespaceRegex, true)
  132. }
  133. if reserveUsers {
  134. registration.Namespaces.RegisterUserIDs(userNamespaceRegex, true)
  135. }
  136. break
  137. }
  138. }
  139. boldCyan.Println("\n==== Registration generated ====")
  140. yamlString, yamlErr := registration.YAML()
  141. if err != nil {
  142. fmt.Println("Failed to return the registration Config:", yamlErr)
  143. return
  144. }
  145. color.Yellow(yamlString)
  146. okInput, readErr := readString(reader, "Does the registration look OK [yes/no]?", "yes")
  147. if readErr != nil {
  148. fmt.Println("Failed to read user Input:", readErr)
  149. return
  150. }
  151. ok := strings.ToLower(okInput)
  152. if ok != yesShort && ok != yes {
  153. fmt.Println("Cancelling generation.")
  154. return
  155. }
  156. path, err := readString(reader, "Where should the registration be saved?", "registration.yaml")
  157. if err != nil {
  158. fmt.Println("Failed to read user Input:", err)
  159. return
  160. }
  161. err = registration.Save(path)
  162. if err != nil {
  163. fmt.Println("Failed to save registration:", err)
  164. return
  165. }
  166. boldGreen.Println("Registration saved.")
  167. config.RegistrationPath = path
  168. boldCyan.Println("\n======= Config generated =======")
  169. color.Yellow(config.YAML())
  170. okString, err := readString(reader, "Does the config look OK [yes/no]?", "yes")
  171. if err != nil {
  172. fmt.Println("Failed to read user Input:", err)
  173. return
  174. }
  175. ok = strings.ToLower(okString)
  176. if ok != yesShort && ok != yes {
  177. fmt.Println("Cancelling generation.")
  178. return
  179. }
  180. path, err = readString(reader, "Where should the config be saved?", "config.yaml")
  181. if err != nil {
  182. fmt.Println("Failed to read user Input:", err)
  183. return
  184. }
  185. err = config.Save(path)
  186. if err != nil {
  187. fmt.Println("Failed to save config:", err)
  188. return
  189. }
  190. boldGreen.Println("Config saved.")
  191. }