welcome: init group memberships for first create (#115)
* rename createAdminAccount to createAccount
* welcome: call memberships init on first user
* auth: add http endpoints to allowed return addresses
* memberships: make init user member of groups as well
---------
Co-authored-by: Giorgi Lekveishvili <lekva@gl-mbp-m1-max.local>
diff --git a/core/installer/welcome/welcome.go b/core/installer/welcome/welcome.go
index 5184a8e..eb7a2dc 100644
--- a/core/installer/welcome/welcome.go
+++ b/core/installer/welcome/welcome.go
@@ -26,11 +26,12 @@
var staticAssets embed.FS
type Server struct {
- port int
- repo installer.RepoIO
- nsCreator installer.NamespaceCreator
- createAccountAddr string
- loginAddr string
+ port int
+ repo installer.RepoIO
+ nsCreator installer.NamespaceCreator
+ createAccountAddr string
+ loginAddr string
+ membershipsInitAddr string
}
func NewServer(
@@ -39,6 +40,7 @@
nsCreator installer.NamespaceCreator,
createAccountAddr string,
loginAddr string,
+ membershipsInitAddr string,
) *Server {
return &Server{
port,
@@ -46,19 +48,20 @@
nsCreator,
createAccountAddr,
loginAddr,
+ membershipsInitAddr,
}
}
func (s *Server) Start() {
r := mux.NewRouter()
r.PathPrefix("/static/").Handler(http.FileServer(http.FS(staticAssets)))
- r.Path("/").Methods("POST").HandlerFunc(s.createAdminAccount)
- r.Path("/").Methods("GET").HandlerFunc(s.createAdminAccountForm)
+ r.Path("/").Methods("POST").HandlerFunc(s.createAccount)
+ r.Path("/").Methods("GET").HandlerFunc(s.createAccountForm)
http.Handle("/", r)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", s.port), nil))
}
-func (s *Server) createAdminAccountForm(w http.ResponseWriter, r *http.Request) {
+func (s *Server) createAccountForm(w http.ResponseWriter, r *http.Request) {
renderRegistrationForm(w, formData{})
}
@@ -150,7 +153,7 @@
}
}
-func (s *Server) createAdminAccount(w http.ResponseWriter, r *http.Request) {
+func (s *Server) createAccount(w http.ResponseWriter, r *http.Request) {
req, err := extractReq(r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -197,6 +200,10 @@
return
}
}
+ if err := s.initMemberships(req.Username); err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
{
config, err := s.repo.ReadConfig()
if err != nil {
@@ -234,3 +241,40 @@
}
renderRegistrationSuccess(w, s.loginAddr)
}
+
+type firstaccount struct {
+ Created bool `json:"created"`
+ Groups []string `json:"groups"`
+}
+
+type initRequest struct {
+ Owner string `json:"owner"`
+ Groups []string `json:"groups"`
+}
+
+func (s *Server) initMemberships(username string) error {
+ inp, err := s.repo.Reader("first-account.yaml")
+ if err != nil {
+ return err
+ }
+ var fa firstaccount
+ if err := installer.ReadYaml(inp, &fa); err != nil {
+ return err
+ }
+ if fa.Created {
+ return nil
+ }
+ req := initRequest{username, fa.Groups}
+ var buf bytes.Buffer
+ if err := json.NewEncoder(&buf).Encode(req); err != nil {
+ return err
+ }
+ if _, err = http.Post(s.membershipsInitAddr, "applications/json", &buf); err != nil {
+ return err
+ }
+ fa.Created = true
+ if err := s.repo.WriteYaml("first-account.yaml", fa); err != nil {
+ return err
+ }
+ return s.repo.CommitAndPush("initialized groups for first account")
+}