Skip to content

Commit 740f4aa

Browse files
committed
change user password via accounts API
1 parent 630f295 commit 740f4aa

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

docs/releases.md

+1
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,7 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
13781378
**Features:**
13791379

13801380
* Add username/password auth to email publishing ([#1164](https://github.com/binwiederhier/ntfy/pull/1164), thanks to [@bishtawi](https://github.com/bishtawi))
1381+
* You can now change passwords via the accounts API (thanks to [@wunter8](https://github.com/wunter8) for implementing)
13811382

13821383
**Bug fixes + maintenance:**
13831384

server/server_admin.go

+6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ func (s *Server) handleUsersAdd(w http.ResponseWriter, r *http.Request, v *visit
4949
if err != nil && !errors.Is(err, user.ErrUserNotFound) {
5050
return err
5151
} else if u != nil {
52+
if req.Force == true {
53+
if err := s.userManager.ChangePassword(req.Username, req.Password); err != nil {
54+
return err
55+
}
56+
return s.writeJSON(w, newSuccessResponse())
57+
}
5258
return errHTTPConflictUserExists
5359
}
5460
var tier *user.Tier

server/server_admin_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,52 @@ func TestUser_AddRemove(t *testing.T) {
4949
"Authorization": util.BasicAuth("phil", "phil"),
5050
})
5151
require.Equal(t, 200, rr.Code)
52+
53+
// Check user was deleted
54+
users, err = s.userManager.Users()
55+
require.Nil(t, err)
56+
require.Equal(t, 3, len(users))
57+
require.Equal(t, "phil", users[0].Name)
58+
require.Equal(t, "emma", users[1].Name)
59+
require.Equal(t, user.Everyone, users[2].Name)
60+
}
61+
62+
func TestUser_ChangePassword(t *testing.T) {
63+
s := newTestServer(t, newTestConfigWithAuthFile(t))
64+
defer s.closeDatabases()
65+
66+
// Create admin
67+
require.Nil(t, s.userManager.AddUser("phil", "phil", user.RoleAdmin))
68+
69+
// Create user via API
70+
rr := request(t, s, "PUT", "/v1/users", `{"username": "ben", "password": "ben"}`, map[string]string{
71+
"Authorization": util.BasicAuth("phil", "phil"),
72+
})
73+
require.Equal(t, 200, rr.Code)
74+
75+
// Try to login with first password
76+
rr = request(t, s, "POST", "/v1/account/token", "", map[string]string{
77+
"Authorization": util.BasicAuth("ben", "ben"),
78+
})
79+
require.Equal(t, 200, rr.Code)
80+
81+
// Change password via API
82+
rr = request(t, s, "PUT", "/v1/users", `{"username": "ben", "password": "ben-two", "force":true}`, map[string]string{
83+
"Authorization": util.BasicAuth("phil", "phil"),
84+
})
85+
require.Equal(t, 200, rr.Code)
86+
87+
// Make sure first password fails
88+
rr = request(t, s, "POST", "/v1/account/token", "", map[string]string{
89+
"Authorization": util.BasicAuth("ben", "ben"),
90+
})
91+
require.Equal(t, 401, rr.Code)
92+
93+
// Try to login with second password
94+
rr = request(t, s, "POST", "/v1/account/token", "", map[string]string{
95+
"Authorization": util.BasicAuth("ben", "ben-two"),
96+
})
97+
require.Equal(t, 200, rr.Code)
5298
}
5399

54100
func TestUser_AddRemove_Failures(t *testing.T) {

server/types.go

+1
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ type apiUserAddRequest struct {
252252
Username string `json:"username"`
253253
Password string `json:"password"`
254254
Tier string `json:"tier"`
255+
Force bool `json:"force"` // Used to change passwords/override existing user
255256
// Do not add 'role' here. We don't want to add admins via the API.
256257
}
257258

0 commit comments

Comments
 (0)