keiji-ctl.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "flag"
  6. "fmt"
  7. "io"
  8. "log"
  9. "net/http"
  10. "net/url"
  11. "os"
  12. "path"
  13. "git.aetherial.dev/aeth/keiji/pkg/auth"
  14. "git.aetherial.dev/aeth/keiji/pkg/controller"
  15. "git.aetherial.dev/aeth/keiji/pkg/storage"
  16. _ "github.com/mattn/go-sqlite3"
  17. )
  18. // authenticate and get the cookie needed to make updates
  19. func authenticate(url, username, password string) *http.Cookie {
  20. client := http.Client{}
  21. b, _ := json.Marshal(auth.Credentials{Username: username, Password: password})
  22. req, _ := http.NewRequest(http.MethodPost, url, bytes.NewReader(b))
  23. req.Header.Add("Content-Type", "application/json")
  24. resp, err := client.Do(req)
  25. if err != nil {
  26. log.Fatal("auth failed: ", err)
  27. }
  28. defer resp.Body.Close()
  29. if resp.StatusCode > 200 {
  30. msg, _ := io.ReadAll(resp.Body)
  31. log.Fatal("Invalid credentials or server error: ", string(msg), "\n Status code: ", resp.StatusCode)
  32. }
  33. cookies := resp.Cookies()
  34. for i := range cookies {
  35. if cookies[i].Name == controller.AUTH_COOKIE_NAME {
  36. return cookies[i]
  37. }
  38. }
  39. log.Fatal("Auth cookie not found.")
  40. return nil
  41. }
  42. // prepare the auth cookie
  43. func prepareCookie(address string) *http.Cookie {
  44. parsedAddr, err := url.Parse(address)
  45. dn := parsedAddr.Hostname()
  46. if err != nil {
  47. log.Fatal("unparseable address: ", address, " error: ", err)
  48. }
  49. var preparedCookie *http.Cookie
  50. if cookie == "" {
  51. log.Fatal("Cookie cannot be empty.")
  52. } else {
  53. preparedCookie = &http.Cookie{Value: cookie, Name: controller.AUTH_COOKIE_NAME, Domain: dn}
  54. }
  55. return preparedCookie
  56. }
  57. var pngFile string
  58. var redirect string
  59. var text string
  60. var col string
  61. var cmd string
  62. var address string
  63. var cookie string
  64. func main() {
  65. flag.StringVar(&pngFile, "png", "", "The location of the PNG to upload")
  66. flag.StringVar(&redirect, "redirect", "", "the website that the navbar will redirect to")
  67. flag.StringVar(&text, "text", "", "the text to display on the menu item")
  68. flag.StringVar(&col, "col", "", "the column to add/populate the admin table item under")
  69. flag.StringVar(&cmd, "cmd", "", "the 'command' for the seed program to use, currently supports options 'admin', 'menu', and 'asset', 'nav'")
  70. flag.StringVar(&address, "address", "https://aetherial.dev", "override the url to contact.")
  71. flag.StringVar(&cookie, "cookie", "", "pass a cookie to bypass direct authentication")
  72. flag.Parse()
  73. client := http.Client{}
  74. switch cmd {
  75. case "auth":
  76. cookie := authenticate(fmt.Sprintf("%s/login", address), os.Getenv("KEIJI_USERNAME"), os.Getenv("KEIJI_PASSWORD"))
  77. fmt.Println(cookie.Value)
  78. case "asset":
  79. b, err := os.ReadFile(pngFile)
  80. if err != nil {
  81. log.Fatal(err)
  82. }
  83. _, fileName := path.Split(pngFile)
  84. item := storage.Asset{
  85. Name: fileName,
  86. Data: b,
  87. }
  88. data, _ := json.Marshal(item)
  89. req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/admin/asset", address), bytes.NewReader(data))
  90. req.AddCookie(prepareCookie(address))
  91. req.Header.Add("Content-Type", "application/json")
  92. resp, err := client.Do(req)
  93. if err != nil {
  94. fmt.Println("There was an error performing the desired request: ", err.Error())
  95. os.Exit(1)
  96. }
  97. if resp.StatusCode > 200 {
  98. defer resp.Body.Close()
  99. b, _ := io.ReadAll(resp.Body)
  100. fmt.Println("There was an error performing the desired request: ", string(b))
  101. os.Exit(2)
  102. }
  103. fmt.Println("navigation bar item upload successfully.")
  104. os.Exit(0)
  105. case "nav":
  106. fmt.Println(string(pngFile))
  107. b, err := os.ReadFile(pngFile)
  108. if err != nil {
  109. log.Fatal(err)
  110. }
  111. _, fileName := path.Split(pngFile)
  112. fmt.Println(fileName)
  113. item := storage.NavBarItem{
  114. Link: fileName,
  115. Redirect: redirect,
  116. Png: b,
  117. }
  118. data, _ := json.Marshal(item)
  119. req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/admin/navbar", address), bytes.NewReader(data))
  120. req.AddCookie(prepareCookie(address))
  121. req.Header.Add("Content-Type", "application/json")
  122. resp, err := client.Do(req)
  123. if err != nil {
  124. fmt.Println("There was an error performing the desired request: ", err.Error())
  125. os.Exit(1)
  126. }
  127. if resp.StatusCode > 200 {
  128. defer resp.Body.Close()
  129. b, _ := io.ReadAll(resp.Body)
  130. fmt.Println("There was an error performing the desired request: ", string(b))
  131. os.Exit(2)
  132. }
  133. fmt.Println("png item upload successfully.")
  134. os.Exit(0)
  135. case "menu":
  136. b, _ := json.Marshal(storage.LinkPair{Text: text, Link: redirect})
  137. req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/admin/menu", address), bytes.NewReader(b))
  138. req.AddCookie(prepareCookie(address))
  139. req.Header.Add("Content-Type", "application/json")
  140. resp, err := client.Do(req)
  141. if err != nil {
  142. fmt.Println("There was an error performing the desired request: ", err.Error())
  143. os.Exit(1)
  144. }
  145. if resp.StatusCode > 200 {
  146. defer resp.Body.Close()
  147. b, _ := io.ReadAll(resp.Body)
  148. fmt.Println("There was an error performing the desired request: ", string(b))
  149. os.Exit(3)
  150. }
  151. fmt.Println("menu item uploaded successfully.")
  152. os.Exit(0)
  153. case "admin":
  154. tables := make(map[string][]storage.TableData)
  155. adminPage := storage.AdminPage{Tables: tables}
  156. adminPage.Tables[col] = append(adminPage.Tables[col], storage.TableData{Link: redirect, DisplayName: text})
  157. b, _ := json.Marshal(adminPage)
  158. req, _ := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/admin/panel", address), bytes.NewReader(b))
  159. req.AddCookie(prepareCookie(address))
  160. req.Header.Add("Content-Type", "application/json")
  161. resp, err := client.Do(req)
  162. if err != nil {
  163. fmt.Println("There was an error performing the desired request: ", err.Error())
  164. os.Exit(1)
  165. }
  166. if resp.StatusCode > 200 {
  167. defer resp.Body.Close()
  168. b, _ := io.ReadAll(resp.Body)
  169. fmt.Println("There was an error performing the desired request: ", string(b))
  170. os.Exit(4)
  171. }
  172. fmt.Println("admin item added successfully.")
  173. os.Exit(0)
  174. }
  175. }