Skip to content

Commit b79b823

Browse files
committed
WIP: Add temporary file when changing htpasswd password
1 parent 1081018 commit b79b823

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

pkg/api/htpasswd.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bufio"
55
"fmt"
66
"os"
7+
"path/filepath"
78
"strings"
89
"sync"
910

@@ -110,10 +111,7 @@ func (hc *HtpasswdClient) ChangePassword(login, supposedOldPassword, newPassword
110111
return zerr.ErrPasswordIsEmpty
111112
}
112113

113-
hc.credMap.rw.RLock()
114-
oldPassphrase, ok := hc.credMap.m[login]
115-
hc.credMap.rw.RUnlock()
116-
114+
oldPassphrase, ok := hc.credMap.Get(login)
117115
if !ok {
118116
return zerr.ErrBadUser
119117
}
@@ -151,10 +149,31 @@ func (hc *HtpasswdClient) ChangePassword(login, supposedOldPassword, newPassword
151149
}
152150
}
153151

154-
// write new content to file
155-
output := strings.Join(lines, "\n")
152+
// write new content to temporary file
153+
// and replace the old file with temporary, so the operation is atomic
154+
output := []byte(strings.Join(lines, "\n"))
155+
156+
tmpfile, err := os.CreateTemp(filepath.Dir(hc.filepath), "htpasswd-*.tmp")
157+
if err != nil {
158+
return fmt.Errorf("error occurred when creating temp htpasswd file: %w", err)
159+
}
160+
161+
if _, err := tmpfile.Write(output); err != nil {
162+
tmpfile.Close()
163+
os.Remove(tmpfile.Name())
164+
return fmt.Errorf("error occurred when writing to temp htpasswd file: %w", err)
165+
}
166+
167+
if err := tmpfile.Close(); err != nil {
168+
os.Remove(tmpfile.Name())
169+
return fmt.Errorf("error occurred when closing temp htpasswd file: %w", err)
170+
}
171+
172+
if err := os.Rename(tmpfile.Name(), hc.filepath); err != nil {
173+
return fmt.Errorf("error occurred while replacing htpasswd file with new file: %w", err)
174+
}
156175

157-
err = os.WriteFile(hc.filepath, []byte(output), constants.DefaultDirPerms)
176+
err = os.WriteFile(hc.filepath, output, constants.DefaultDirPerms)
158177
if err != nil {
159178
return fmt.Errorf("error occurred while writing to creds-file: %w", err)
160179
}

pkg/api/routes.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2248,14 +2248,16 @@ func (rh *RouteHandler) ChangePassword(resp http.ResponseWriter, req *http.Reque
22482248

22492249
userAc, err := reqCtx.UserAcFromContext(req.Context())
22502250
if err != nil {
2251-
resp.WriteHeader(http.StatusNotFound)
2251+
resp.WriteHeader(http.StatusInternalServerError)
22522252

22532253
return
22542254
}
22552255

22562256
username := userAc.GetUsername()
22572257
if username == "" {
22582258
resp.WriteHeader(http.StatusNotFound)
2259+
2260+
return
22592261
}
22602262

22612263
if err := rh.c.HtpasswdClient.ChangePassword(username, reqBody.OldPassword, reqBody.NewPassword); err != nil {

0 commit comments

Comments
 (0)