setup: auto login after creating the first admin

This commit is contained in:
Nicola Murino 2021-05-16 21:36:57 +02:00
parent 8ecf64f481
commit 60cfbd2989
No known key found for this signature in database
GPG key ID: 2F1FB59433D5A8CB
3 changed files with 61 additions and 48 deletions

View file

@ -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)

View file

@ -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))

View file

@ -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)