blob: 04e07928793a3cf0edf6d579b2b950ba8855f31c [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
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040011 "github.com/gorilla/mux"
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040012
13 "github.com/giolekva/pcloud/core/installer"
14)
15
Giorgi Lekveishvilib4a9c982023-06-22 15:17:02 +040016//go:embed create-admin-account.html
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040017var indexHtml []byte
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040018
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() {
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040037 r := mux.NewRouter()
38 r.PathPrefix("/static/").Handler(http.FileServer(http.FS(staticAssets)))
39 r.Path("/").Methods("POST").HandlerFunc(s.createAdminAccount)
40 r.Path("/").Methods("GET").HandlerFunc(s.createAdminAccountForm)
41 http.Handle("/", r)
42 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil))
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040043}
44
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040045func (s *Server) createAdminAccountForm(w http.ResponseWriter, _ *http.Request) {
46 if _, err := w.Write(indexHtml); err != nil {
47 http.Error(w, err.Error(), http.StatusInternalServerError)
48 return
49 }
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040050}
51
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040052type createAccountReq struct {
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040053 Username string `json:"username,omitempty"`
54 Password string `json:"password,omitempty"` // TODO(giolekva): actually use this
55 GandiAPIToken string `json:"gandiAPIToken,omitempty"`
56 SecretToken string `json:"secretToken,omitempty"`
57}
58
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040059func getFormValue(v url.Values, name string) (string, error) {
60 items, ok := v[name]
61 if !ok || len(items) != 1 {
62 return "", fmt.Errorf("%s not found", name)
63 }
64 return items[0], nil
65}
66
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040067func extractReq(r *http.Request) (createAccountReq, error) {
68 var req createAccountReq
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040069 if err := func() error {
70 var err error
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040071 if err = r.ParseForm(); err != nil {
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040072 return err
73 }
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040074 if req.Username, err = getFormValue(r.PostForm, "username"); err != nil {
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040075 return err
76 }
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040077 if req.Password, err = getFormValue(r.PostForm, "password"); err != nil {
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040078 return err
79 }
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040080 if req.GandiAPIToken, err = getFormValue(r.PostForm, "gandi-api-token"); err != nil {
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040081 return err
82 }
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040083 if req.SecretToken, err = getFormValue(r.PostForm, "secret-token"); err != nil {
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040084 return err
85 }
86 return nil
87 }(); err != nil {
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040088 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
89 return createAccountReq{}, err
Giorgi Lekveishvili6b887be2023-06-22 14:38:19 +040090 }
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +040091 }
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +040092 return req, nil
93}
94
95func (s *Server) createAdminAccount(w http.ResponseWriter, r *http.Request) {
Giorgi Lekveishvili39913692023-12-05 08:58:08 +040096 req, err := extractReq(r)
97 if err != nil {
98 http.Error(w, err.Error(), http.StatusInternalServerError)
99 return
100 }
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400101 // TODO(giolekva): accounts-ui create user req
102 {
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400103 config, err := s.repo.ReadConfig()
104 if err != nil {
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +0400105 http.Error(w, err.Error(), http.StatusInternalServerError)
106 return
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400107 }
108 if err != nil {
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +0400109 http.Error(w, err.Error(), http.StatusInternalServerError)
110 return
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400111 }
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +0400112 nsGen := installer.NewPrefixGenerator(config.Values.NamespacePrefix)
113 suffixGen := installer.NewEmptySuffixGenerator()
Giorgi Lekveishvili7fb28bf2023-06-24 19:51:16 +0400114 appManager, err := installer.NewAppManager(s.repo, s.nsCreator)
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400115 if err != nil {
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +0400116 http.Error(w, err.Error(), http.StatusInternalServerError)
117 return
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400118 }
119 appsRepo := installer.NewInMemoryAppRepository(installer.CreateAllApps())
120 {
Giorgi Lekveishvili39913692023-12-05 08:58:08 +0400121 app, err := appsRepo.Find("headscale-user")
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400122 if err != nil {
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +0400123 http.Error(w, err.Error(), http.StatusInternalServerError)
124 return
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400125 }
Giorgi Lekveishvili6e813182023-06-30 13:45:30 +0400126 if err := appManager.Install(*app, nsGen, suffixGen, map[string]any{
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400127 "Username": req.Username,
Giorgi Lekveishvili39913692023-12-05 08:58:08 +0400128 "PreAuthKey": map[string]any{
129 "Enabled": false,
130 },
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400131 }); err != nil {
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +0400132 http.Error(w, err.Error(), http.StatusInternalServerError)
133 return
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400134 }
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400135 }
136 }
Giorgi Lekveishvili123a3672023-12-04 13:01:29 +0400137 if _, err := w.Write([]byte("OK")); err != nil {
138 http.Error(w, err.Error(), http.StatusInternalServerError)
139 return
140 }
Giorgi Lekveishvili12850ee2023-06-22 13:11:17 +0400141}