blob: d34580fb020a632d2648286577828059c4ec2772 [file] [log] [blame]
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +04001package welcome
2
3import (
4 "embed"
5 "encoding/json"
6 "fmt"
7 "log"
8 "net/http"
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +04009 "net/url"
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040010
11 "github.com/labstack/echo/v4"
12
13 "github.com/giolekva/pcloud/core/installer"
14)
15
Giorgi Lekveishvilib4a9c982023-06-22 15:17:02 +040016//go:embed create-admin-account.html
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040017var indexHtml string
18
19//go:embed static/*
20var staticAssets embed.FS
21
22type Server struct {
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040023 port int
24 repo installer.RepoIO
25 nsCreator installer.NamespaceCreator
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040026}
27
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040028func NewServer(port int, repo installer.RepoIO, nsCreator installer.NamespaceCreator) *Server {
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040029 return &Server{
30 port,
31 repo,
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040032 nsCreator,
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040033 }
34}
35
36func (s *Server) Start() {
37 e := echo.New()
38 e.StaticFS("/static", echo.MustSubFS(staticAssets, "static"))
39 e.POST("/create-admin-account", s.createAdminAccount)
40 e.GET("/", s.createAdminAccountForm)
41 log.Fatal(e.Start(fmt.Sprintf(":%d", s.port)))
42}
43
44func (s *Server) createAdminAccountForm(c echo.Context) error {
45 return c.HTML(http.StatusOK, indexHtml)
46}
47
48type createAdminAccountReq struct {
49 Username string `json:"username,omitempty"`
50 Password string `json:"password,omitempty"` // TODO(giolekva): actually use this
51 GandiAPIToken string `json:"gandiAPIToken,omitempty"`
52 SecretToken string `json:"secretToken,omitempty"`
53}
54
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040055func getFormValue(v url.Values, name string) (string, error) {
56 items, ok := v[name]
57 if !ok || len(items) != 1 {
58 return "", fmt.Errorf("%s not found", name)
59 }
60 return items[0], nil
61}
62
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040063func (s *Server) createAdminAccount(c echo.Context) error {
64 var req createAdminAccountReq
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040065 if err := func() error {
66 var err error
67 f, err := c.FormParams()
68 if err != nil {
69 return err
70 }
71 if req.Username, err = getFormValue(f, "username"); err != nil {
72 return err
73 }
74 if req.Password, err = getFormValue(f, "password"); err != nil {
75 return err
76 }
77 if req.GandiAPIToken, err = getFormValue(f, "gandi-api-token"); err != nil {
78 return err
79 }
80 if req.SecretToken, err = getFormValue(f, "secret-token"); err != nil {
81 return err
82 }
83 return nil
84 }(); err != nil {
85 if err := json.NewDecoder(c.Request().Body).Decode(&req); err != nil {
86 return err
87 }
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040088 }
89 // TODO(giolekva): accounts-ui create user req
90 {
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +040091 config, err := s.repo.ReadConfig()
92 if err != nil {
93 return err
94 }
95 if err != nil {
96 return err
97 }
98 nsGen := installer.NewPrefixGenerator(config.Values.Id + "-")
99 appManager, err := installer.NewAppManager(s.repo, s.nsCreator)
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400100 if err != nil {
101 return err
102 }
103 appsRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
104 {
105 app, err := appsRepo.Find("certificate-issuer-private")
106 if err != nil {
107 return err
108 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400109 if err := appManager.Install(*app, nsGen, map[string]any{
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400110 "GandiAPIToken": req.GandiAPIToken,
111 }); err != nil {
112 return err
113 }
114 }
115 {
116 app, err := appsRepo.Find("tailscale-proxy")
117 if err != nil {
118 return err
119 }
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400120 if err := appManager.Install(*app, nsGen, map[string]any{
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400121 "Username": req.Username,
122 "IPSubnet": "10.1.0.0/24", // TODO(giolekva): this should be taken from the config generated during new env creation
123 }); err != nil {
124 return err
125 }
126 // TODO(giolekva): headscale accept routes
127 }
128 }
129 return c.String(http.StatusOK, "OK")
130}