Browse Source

Enable setting password change requirements in user templates

Signed-off-by: Nicola Murino <[email protected]>
Nicola Murino 4 months ago
parent
commit
c2835bc19d
3 changed files with 49 additions and 12 deletions
  1. 22 0
      internal/httpd/httpd_test.go
  2. 17 12
      internal/httpd/webadmin.go
  3. 10 0
      templates/webadmin/user.html

+ 22 - 0
internal/httpd/httpd_test.go

@@ -22389,8 +22389,30 @@ func TestUserSaveFromTemplateMock(t *testing.T) {
 
 	u1, _, err := httpdtest.GetUserByUsername(user1, http.StatusOK)
 	assert.NoError(t, err)
+	assert.False(t, u1.Filters.RequirePasswordChange)
 	u2, _, err := httpdtest.GetUserByUsername(user2, http.StatusOK)
 	assert.NoError(t, err)
+	assert.False(t, u2.Filters.RequirePasswordChange)
+
+	_, err = httpdtest.RemoveUser(u1, http.StatusOK)
+	assert.NoError(t, err)
+	_, err = httpdtest.RemoveUser(u2, http.StatusOK)
+	assert.NoError(t, err)
+
+	form.Add("tpl_require_password_change", "checked")
+	b, contentType, _ = getMultipartFormData(form, "", "")
+	req, _ = http.NewRequest(http.MethodPost, webTemplateUser, &b)
+	setJWTCookieForReq(req, token)
+	req.Header.Set("Content-Type", contentType)
+	rr = executeRequest(req)
+	checkResponseCode(t, http.StatusSeeOther, rr)
+
+	u1, _, err = httpdtest.GetUserByUsername(user1, http.StatusOK)
+	assert.NoError(t, err)
+	assert.True(t, u1.Filters.RequirePasswordChange)
+	u2, _, err = httpdtest.GetUserByUsername(user2, http.StatusOK)
+	assert.NoError(t, err)
+	assert.True(t, u2.Filters.RequirePasswordChange)
 
 	_, err = httpdtest.RemoveUser(u1, http.StatusOK)
 	assert.NoError(t, err)

+ 17 - 12
internal/httpd/webadmin.go

@@ -348,9 +348,10 @@ type messagePage struct {
 }
 
 type userTemplateFields struct {
-	Username   string
-	Password   string
-	PublicKeys []string
+	Username         string
+	Password         string
+	PublicKeys       []string
+	RequirePwdChange bool
 }
 
 func loadAdminTemplates(templatesPath string) {
@@ -1225,9 +1226,10 @@ func getUsersForTemplate(r *http.Request) []userTemplateFields {
 
 		users[username] = true
 		res = append(res, userTemplateFields{
-			Username:   username,
-			Password:   password,
-			PublicKeys: []string{publicKey},
+			Username:         username,
+			Password:         password,
+			PublicKeys:       []string{publicKey},
+			RequirePwdChange: r.Form.Get("tpl_require_password_change") != "",
 		})
 	}
 
@@ -1910,6 +1912,7 @@ func getUserFromTemplate(user dataprovider.User, template userTemplateFields) da
 	user.Username = template.Username
 	user.Password = template.Password
 	user.PublicKeys = template.PublicKeys
+	user.Filters.RequirePasswordChange = template.RequirePwdChange
 	replacements := make(map[string]string)
 	replacements["%username%"] = user.Username
 	if user.Password != "" && !user.IsPasswordHashed() {
@@ -3461,9 +3464,10 @@ func (s *httpdServer) handleWebAddUserPost(w http.ResponseWriter, r *http.Reques
 		return
 	}
 	user = getUserFromTemplate(user, userTemplateFields{
-		Username:   user.Username,
-		Password:   user.Password,
-		PublicKeys: user.PublicKeys,
+		Username:         user.Username,
+		Password:         user.Password,
+		PublicKeys:       user.PublicKeys,
+		RequirePwdChange: user.Filters.RequirePasswordChange,
 	})
 	if claims.Role != "" {
 		user.Role = claims.Role
@@ -3518,9 +3522,10 @@ func (s *httpdServer) handleWebUpdateUserPost(w http.ResponseWriter, r *http.Req
 	updateEncryptedSecrets(&updatedUser.FsConfig, &user.FsConfig)
 
 	updatedUser = getUserFromTemplate(updatedUser, userTemplateFields{
-		Username:   updatedUser.Username,
-		Password:   updatedUser.Password,
-		PublicKeys: updatedUser.PublicKeys,
+		Username:         updatedUser.Username,
+		Password:         updatedUser.Password,
+		PublicKeys:       updatedUser.PublicKeys,
+		RequirePwdChange: updatedUser.Filters.RequirePasswordChange,
 	})
 	if claims.Role != "" {
 		updatedUser.Role = claims.Role

+ 10 - 0
templates/webadmin/user.html

@@ -91,6 +91,16 @@ explicit grant from the SFTPGo Team ([email protected]).
                                 <span data-i18n="general.add">Add</span>
                             </a>
                         </div>
+
+                        <div class="form-group row align-items-center mt-10">
+                            <label data-i18n="user.require_pwd_change" class="col-md-3 col-form-label" for="idTmplRequirePasswordChange">Require password change</label>
+                            <div class="col-md-9">
+                                <div class="form-check form-switch form-check-custom form-check-solid">
+                                    <input class="form-check-input" type="checkbox" id="idTmplRequirePasswordChange" name="tpl_require_password_change"/>
+                                </div>
+                            </div>
+                        </div>
+
                     </div>
                 </div>
             </div>