Просмотр исходного кода

change user password via accounts API

Hunter Kehoe 1 год назад
Родитель
Сommit
8f9dafce20
4 измененных файлов с 54 добавлено и 0 удалено
  1. 1 0
      docs/releases.md
  2. 6 0
      server/server_admin.go
  3. 46 0
      server/server_admin_test.go
  4. 1 0
      server/types.go

+ 1 - 0
docs/releases.md

@@ -1381,6 +1381,7 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
 * Write VAPID keys to file in `ntfy webpush --output-file` ([#1138](https://github.com/binwiederhier/ntfy/pull/1138), thanks to [@nogweii](https://github.com/nogweii))
 * Add Docker major/minor version to image tags ([#1271](https://github.com/binwiederhier/ntfy/pull/1271), thanks to [@RoboMagus](https://github.com/RoboMagus))
 * Add `latest` subscription param for grabbing just the most recent message ([#1216](https://github.com/binwiederhier/ntfy/pull/1216), thanks to [@wunter8](https://github.com/wunter8))
+* You can now change passwords via the accounts API (thanks to [@wunter8](https://github.com/wunter8) for implementing)
 
 **Bug fixes + maintenance:**
 

+ 6 - 0
server/server_admin.go

@@ -49,6 +49,12 @@ func (s *Server) handleUsersAdd(w http.ResponseWriter, r *http.Request, v *visit
 	if err != nil && !errors.Is(err, user.ErrUserNotFound) {
 		return err
 	} else if u != nil {
+		if req.Force == true {
+			if err := s.userManager.ChangePassword(req.Username, req.Password); err != nil {
+				return err
+			}
+			return s.writeJSON(w, newSuccessResponse())
+		}
 		return errHTTPConflictUserExists
 	}
 	var tier *user.Tier

+ 46 - 0
server/server_admin_test.go

@@ -49,6 +49,52 @@ func TestUser_AddRemove(t *testing.T) {
 		"Authorization": util.BasicAuth("phil", "phil"),
 	})
 	require.Equal(t, 200, rr.Code)
+
+	// Check user was deleted
+	users, err = s.userManager.Users()
+	require.Nil(t, err)
+	require.Equal(t, 3, len(users))
+	require.Equal(t, "phil", users[0].Name)
+	require.Equal(t, "emma", users[1].Name)
+	require.Equal(t, user.Everyone, users[2].Name)
+}
+
+func TestUser_ChangePassword(t *testing.T) {
+	s := newTestServer(t, newTestConfigWithAuthFile(t))
+	defer s.closeDatabases()
+
+	// Create admin
+	require.Nil(t, s.userManager.AddUser("phil", "phil", user.RoleAdmin))
+
+	// Create user via API
+	rr := request(t, s, "PUT", "/v1/users", `{"username": "ben", "password": "ben"}`, map[string]string{
+		"Authorization": util.BasicAuth("phil", "phil"),
+	})
+	require.Equal(t, 200, rr.Code)
+
+	// Try to login with first password
+	rr = request(t, s, "POST", "/v1/account/token", "", map[string]string{
+		"Authorization": util.BasicAuth("ben", "ben"),
+	})
+	require.Equal(t, 200, rr.Code)
+
+	// Change password via API
+	rr = request(t, s, "PUT", "/v1/users", `{"username": "ben", "password": "ben-two", "force":true}`, map[string]string{
+		"Authorization": util.BasicAuth("phil", "phil"),
+	})
+	require.Equal(t, 200, rr.Code)
+
+	// Make sure first password fails
+	rr = request(t, s, "POST", "/v1/account/token", "", map[string]string{
+		"Authorization": util.BasicAuth("ben", "ben"),
+	})
+	require.Equal(t, 401, rr.Code)
+
+	// Try to login with second password
+	rr = request(t, s, "POST", "/v1/account/token", "", map[string]string{
+		"Authorization": util.BasicAuth("ben", "ben-two"),
+	})
+	require.Equal(t, 200, rr.Code)
 }
 
 func TestUser_AddRemove_Failures(t *testing.T) {

+ 1 - 0
server/types.go

@@ -257,6 +257,7 @@ type apiUserAddRequest struct {
 	Username string `json:"username"`
 	Password string `json:"password"`
 	Tier     string `json:"tier"`
+	Force    bool   `json:"force"` // Used to change passwords/override existing user
 	// Do not add 'role' here. We don't want to add admins via the API.
 }