diff --git a/httpd/httpd_test.go b/httpd/httpd_test.go index 02430932..358f7465 100644 --- a/httpd/httpd_test.go +++ b/httpd/httpd_test.go @@ -5192,6 +5192,11 @@ func TestWebAdminSetupMock(t *testing.T) { rr = executeRequest(req) checkResponseCode(t, http.StatusFound, rr) assert.Equal(t, webAdminSetupPath, rr.Header().Get("Location")) + req, err = http.NewRequest(http.MethodGet, webLoginPath, nil) + assert.NoError(t, err) + rr = executeRequest(req) + checkResponseCode(t, http.StatusFound, rr) + assert.Equal(t, webAdminSetupPath, rr.Header().Get("Location")) csrfToken, err := getCSRFToken(httpBaseURL + webAdminSetupPath) assert.NoError(t, err) @@ -5250,8 +5255,8 @@ func TestWebAdminSetupMock(t *testing.T) { assert.NoError(t, err) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") rr = executeRequest(req) - checkResponseCode(t, http.StatusSeeOther, rr) - assert.Equal(t, webLoginPath, rr.Header().Get("Location")) + checkResponseCode(t, http.StatusFound, rr) + assert.Equal(t, webUsersPath, rr.Header().Get("Location")) // if we resubmit the form we get a bad request, an admin already exists req, err = http.NewRequest(http.MethodPost, webAdminSetupPath, bytes.NewBuffer([]byte(form.Encode()))) assert.NoError(t, err) diff --git a/httpd/server.go b/httpd/server.go index 9d08c96c..cd884def 100644 --- a/httpd/server.go +++ b/httpd/server.go @@ -197,13 +197,61 @@ func (s *httpdServer) handleWebAdminLoginPost(w http.ResponseWriter, r *http.Req renderLoginPage(w, err.Error()) return } + s.loginAdmin(w, r, &admin) +} + +func (s *httpdServer) handleWebAdminSetupPost(w http.ResponseWriter, r *http.Request) { + r.Body = http.MaxBytesReader(w, r.Body, maxLoginPostSize) + if dataprovider.HasAdmin() { + renderBadRequestPage(w, r, errors.New("an admin user already exists")) + return + } + err := r.ParseForm() + if err != nil { + renderAdminSetupPage(w, r, "", err.Error()) + return + } + if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil { + renderForbiddenPage(w, r, err.Error()) + return + } + username := r.Form.Get("username") + password := r.Form.Get("password") + confirmPassword := r.Form.Get("confirm_password") + if username == "" { + renderAdminSetupPage(w, r, username, "Please set a username") + return + } + if password == "" { + renderAdminSetupPage(w, r, username, "Please set a password") + return + } + if password != confirmPassword { + renderAdminSetupPage(w, r, username, "Passwords mismatch") + return + } + admin := dataprovider.Admin{ + Username: username, + Password: password, + Status: 1, + Permissions: []string{dataprovider.PermAdminAny}, + } + err = dataprovider.AddAdmin(&admin) + if err != nil { + renderAdminSetupPage(w, r, username, err.Error()) + return + } + s.loginAdmin(w, r, &admin) +} + +func (s *httpdServer) loginAdmin(w http.ResponseWriter, r *http.Request, admin *dataprovider.Admin) { c := jwtTokenClaims{ Username: admin.Username, Permissions: admin.Permissions, Signature: admin.GetSignature(), } - err = c.createAndSetCookie(w, r, s.tokenAuth, tokenAudienceWebAdmin) + err := c.createAndSetCookie(w, r, s.tokenAuth, tokenAudienceWebAdmin) if err != nil { logger.Warn(logSender, "", "unable to set admin login cookie %v", err) renderLoginPage(w, err.Error()) @@ -539,7 +587,7 @@ func (s *httpdServer) initializeRouter() { s.router.Get(webLoginPath, handleWebLogin) s.router.Post(webLoginPath, s.handleWebAdminLoginPost) s.router.Get(webAdminSetupPath, handleWebAdminSetupGet) - s.router.Post(webAdminSetupPath, handleWebAdminSetupPost) + s.router.Post(webAdminSetupPath, s.handleWebAdminSetupPost) s.router.Group(func(router chi.Router) { router.Use(jwtauth.Verify(s.tokenAuth, jwtauth.TokenFromCookie)) diff --git a/httpd/webadmin.go b/httpd/webadmin.go index 968b616f..7c234238 100644 --- a/httpd/webadmin.go +++ b/httpd/webadmin.go @@ -1038,6 +1038,10 @@ func handleWebLogout(w http.ResponseWriter, r *http.Request) { } func handleWebLogin(w http.ResponseWriter, r *http.Request) { + if !dataprovider.HasAdmin() { + http.Redirect(w, r, webAdminSetupPath, http.StatusFound) + return + } renderLoginPage(w, "") } @@ -1125,50 +1129,6 @@ func handleWebAdminSetupGet(w http.ResponseWriter, r *http.Request) { renderAdminSetupPage(w, r, "", "") } -func handleWebAdminSetupPost(w http.ResponseWriter, r *http.Request) { - r.Body = http.MaxBytesReader(w, r.Body, maxLoginPostSize) - if dataprovider.HasAdmin() { - renderBadRequestPage(w, r, errors.New("an admin user already exists")) - return - } - err := r.ParseForm() - if err != nil { - renderAdminSetupPage(w, r, "", err.Error()) - return - } - if err := verifyCSRFToken(r.Form.Get(csrfFormToken)); err != nil { - renderForbiddenPage(w, r, err.Error()) - return - } - username := r.Form.Get("username") - password := r.Form.Get("password") - confirmPassword := r.Form.Get("confirm_password") - if username == "" { - renderAdminSetupPage(w, r, username, "Please set a username") - return - } - if password == "" { - renderAdminSetupPage(w, r, username, "Please set a password") - return - } - if password != confirmPassword { - renderAdminSetupPage(w, r, username, "Passwords mismatch") - return - } - admin := dataprovider.Admin{ - Username: username, - Password: password, - Status: 1, - Permissions: []string{dataprovider.PermAdminAny}, - } - err = dataprovider.AddAdmin(&admin) - if err != nil { - renderAdminSetupPage(w, r, username, err.Error()) - return - } - http.Redirect(w, r, webLoginPath, http.StatusSeeOther) -} - func handleWebAddAdminGet(w http.ResponseWriter, r *http.Request) { admin := &dataprovider.Admin{Status: 1} renderAddUpdateAdminPage(w, r, admin, "", true)