فهرست منبع

Allow admin user to reset passwords (#1765)

See #960
Alexis Degrugillier 8 سال پیش
والد
کامیت
ac3e38359b

+ 39 - 17
app/Controllers/userController.php

@@ -44,29 +44,54 @@ class FreshRSS_user_Controller extends Minz_ActionController {
 		return preg_match('/^' . self::USERNAME_PATTERN . '$/', $username) === 1;
 	}
 
-	public static function updateContextUser($passwordPlain, $apiPasswordPlain, $userConfigUpdated = array()) {
+	public static function updateUser($user, $passwordPlain, $apiPasswordPlain, $userConfigUpdated = array()) {
+		$userConfig = get_user_configuration($user);
 		if ($passwordPlain != '') {
 			$passwordHash = self::hashPassword($passwordPlain);
-			FreshRSS_Context::$user_conf->passwordHash = $passwordHash;
+			$userConfig->passwordHash = $passwordHash;
 		}
 
 		if ($apiPasswordPlain != '') {
 			$apiPasswordHash = self::hashPassword($apiPasswordPlain);
-			FreshRSS_Context::$user_conf->apiPasswordHash = $apiPasswordHash;
+			$userConfig->apiPasswordHash = $apiPasswordHash;
 		}
 
 		if (is_array($userConfigUpdated)) {
 			foreach ($userConfigUpdated as $configName => $configValue) {
 				if ($configValue !== null) {
-					FreshRSS_Context::$user_conf->_param($configName, $configValue);
+					$userConfig->_param($configName, $configValue);
 				}
 			}
 		}
 
-		$ok = FreshRSS_Context::$user_conf->save();
+		$ok = $userConfig->save();
 		return $ok;
 	}
 
+	public function updateAction() {
+		if (Minz_Request::isPost()) {
+			$passwordPlain = Minz_Request::param('newPasswordPlain', '', true);
+			Minz_Request::_param('newPasswordPlain');	//Discard plain-text password ASAP
+			$_POST['newPasswordPlain'] = '';
+
+			$apiPasswordPlain = Minz_Request::param('apiPasswordPlain', '', true);
+
+			$username = Minz_Request::param('username');
+			$ok = self::updateUser($username, $passwordPlain, $apiPasswordPlain, array(
+					'token' => Minz_Request::param('token', null),
+				));
+
+			if ($ok) {
+				Minz_Request::good(_t('feedback.user.updated', $username),
+				                   array('c' => 'user', 'a' => 'manage'));
+			} else {
+				Minz_Request::bad(_t('feedback.user.updated.error', $username),
+				                  array('c' => 'user', 'a' => 'manage'));
+			}
+
+		}
+	}
+
 	/**
 	 * This action displays the user profile page.
 	 */
@@ -84,7 +109,7 @@ class FreshRSS_user_Controller extends Minz_ActionController {
 
 			$apiPasswordPlain = Minz_Request::param('apiPasswordPlain', '', true);
 
-			$ok = self::updateContextUser($passwordPlain, $apiPasswordPlain, array(
+			$ok = self::updateUser(Minz_Session::param('currentUser'), $passwordPlain, $apiPasswordPlain, array(
 					'token' => Minz_Request::param('token', null),
 				));
 
@@ -110,19 +135,16 @@ class FreshRSS_user_Controller extends Minz_ActionController {
 
 		Minz_View::prependTitle(_t('admin.user.title') . ' · ');
 
-		// Get the correct current user.
-		$username = Minz_Request::param('u', Minz_Session::param('currentUser'));
-		if (!FreshRSS_UserDAO::exist($username)) {
-			$username = Minz_Session::param('currentUser');
-		}
-		$this->view->current_user = $username;
+		$this->view->current_user = Minz_Request::param('u');
 
-		// Get information about the current user.
-		$entryDAO = FreshRSS_Factory::createEntryDao($this->view->current_user);
-		$this->view->nb_articles = $entryDAO->count();
+		if ($this->view->current_user) {
+			// Get information about the current user.
+			$entryDAO = FreshRSS_Factory::createEntryDao($this->view->current_user);
+			$this->view->nb_articles = $entryDAO->count();
 
-		$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
-		$this->view->size_user = $databaseDAO->size();
+			$databaseDAO = FreshRSS_Factory::createDatabaseDAO();
+			$this->view->size_user = $databaseDAO->size();
+		}
 	}
 
 	public static function createUser($new_user_name, $passwordPlain, $apiPasswordPlain, $userConfig = array(), $insertDefaultFeeds = true) {

+ 3 - 0
app/i18n/cz/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s článků (%s)',
 		'create' => 'Vytvořit nového uživatele',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'Jazyk',
 		'number' => 'Zatím je vytvořen %d účet',
 		'numbers' => 'Zatím je vytvořeno %d účtů',
 		'password_form' => 'Heslo<br /><small>(pro přihlášení webovým formulářem)</small>',
 		'password_format' => 'Alespoň 7 znaků',
+		'selected' => 'Selected user', // TODO
 		'title' => 'Správa uživatelů',
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'Seznam uživatelů',
 		'username' => 'Přihlašovací jméno',
 		'users' => 'Uživatelé',

+ 4 - 0
app/i18n/cz/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'Uživatel %s byl smazán',
 			'error' => 'Uživatele %s nelze smazat',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => 'Váš profil nelze změnit',

+ 1 - 0
app/i18n/cz/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'Navštívit WWW stránku',
 		'submit' => 'Odeslat',
 		'truncate' => 'Smazat všechny články',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Email',

+ 3 - 0
app/i18n/de/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s Artikel (%s)',
 		'create' => 'Neuen Benutzer erstellen',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'Sprache',
 		'number' => 'Es wurde bis jetzt %d Account erstellt',
 		'numbers' => 'Es wurden bis jetzt %d Accounts erstellt',
 		'password_form' => 'Passwort<br /><small>(für die Anmeldemethode per Webformular)</small>',
 		'password_format' => 'mindestens 7 Zeichen',
+		'selected' => 'Selected user', // TODO
 		'title' => 'Benutzer verwalten',
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'Liste der Benutzer',
 		'username' => 'Nutzername',
 		'users' => 'Benutzer',

+ 4 - 0
app/i18n/de/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'Der Benutzer %s ist gelöscht worden',
 			'error' => 'Der Benutzer %s kann nicht gelöscht werden',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => 'Ihr Profil kann nicht geändert werden',

+ 1 - 0
app/i18n/de/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'Webseite ansehen',
 		'submit' => 'Abschicken',
 		'truncate' => 'Alle Artikel löschen',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'E-Mail-Adresse',

+ 3 - 0
app/i18n/en/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s articles (%s)',
 		'create' => 'Create new user',
+		'delete_users' => 'Delete user',
 		'language' => 'Language',
 		'number' => 'There is %d account created',
 		'numbers' => 'There are %d accounts created',
 		'password_form' => 'Password<br /><small>(for the Web-form login method)</small>',
 		'password_format' => 'At least 7 characters',
+		'selected' => 'Selected user',
 		'title' => 'Manage users',
+		'update_users' => 'Update user',
 		'user_list' => 'List of users',
 		'username' => 'Username',
 		'users' => 'Users',

+ 4 - 0
app/i18n/en/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'User %s has been deleted',
 			'error' => 'User %s cannot be deleted',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated',
+			'error' => 'User %s has not been updated',
+		),
 	),
 	'profile' => array(
 		'error' => 'Your profile cannot be modified',

+ 1 - 0
app/i18n/en/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'See website',
 		'submit' => 'Submit',
 		'truncate' => 'Delete all articles',
+		'update' => 'Update',
 	),
 	'auth' => array(
 		'email' => 'Email address',

+ 3 - 0
app/i18n/es/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s articles (%s)',
 		'create' => 'Crear nuevo usuario',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'Idioma',
 		'number' => 'Hay %d cuenta creada',
 		'numbers' => 'Hay %d cuentas creadas',
 		'password_form' => 'Contraseña<br /><small>(para el método de identificación por formulario web)</small>',
 		'password_format' => 'Mínimo de 7 caracteres',
+		'selected' => 'Selected user', // TODO
 		'title' => 'Administrar usuarios',
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'Lista de usuarios',
 		'username' => 'Nombre de usuario',
 		'users' => 'Usuarios',

+ 4 - 0
app/i18n/es/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'El usuario %s ha sido eliminado',
 			'error' => 'El usuario %s no ha podido ser eliminado',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => 'Tu perfil no puede ser modificado',

+ 1 - 0
app/i18n/es/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'Ver web',
 		'submit' => 'Enviar',
 		'truncate' => 'Borrar todos los artículos',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Correo electrónico',

+ 3 - 0
app/i18n/fr/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s articles (%s)',
 		'create' => 'Créer un nouvel utilisateur',
+		'delete_users' => 'Supprimer un utilisateur',
 		'language' => 'Langue',
 		'number' => '%d compte a déjà été créé',
 		'numbers' => '%d comptes ont déjà été créés',
 		'password_form' => 'Mot de passe<br /><small>(pour connexion par formulaire)</small>',
 		'password_format' => '7 caractères minimum',
+		'selected' => 'Utilisateur sélectionné',
 		'title' => 'Gestion des utilisateurs',
+		'update_users' => 'Mettre à jour un utilisateur',
 		'user_list' => 'Liste des utilisateurs',
 		'username' => 'Nom d’utilisateur',
 		'users' => 'Utilisateurs',

+ 4 - 0
app/i18n/fr/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'L’utilisateur %s a été supprimé.',
 			'error' => 'L’utilisateur %s ne peut pas être supprimé.',
 		),
+		'updated' => array(
+			'_' => 'L’utilisateur %s a été mis à jour',
+			'error' => 'L’utilisateur %s n’a pas été mis à jour',
+		),
 	),
 	'profile' => array(
 		'error' => 'Votre profil n’a pas pu être mis à jour',

+ 1 - 0
app/i18n/fr/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'Voir le site',
 		'submit' => 'Valider',
 		'truncate' => 'Supprimer tous les articles',
+		'update' => 'Mettre à jour',
 	),
 	'auth' => array(
 		'email' => 'Adresse courriel',

+ 3 - 0
app/i18n/he/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s articles (%s)', // @todo
 		'create' => 'יצירת משתמש חדש',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'שפה',
 		'number' => 'There is %d account created', // @todo
 		'numbers' => 'There are %d accounts created', // @todo
 		'password_form' => 'סיסמה<br /><small>(לשימוש בטפוס ההרשמה)</small>',
 		'password_format' => 'At least 7 characters', // @todo
+		'selected' => 'Selected user', // TODO
 		'title' => 'Manage users', // @todo
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'רשימת משתמשים',
 		'username' => 'שם משתמש',
 		'users' => 'משתמשים',

+ 4 - 0
app/i18n/he/feedback.php

@@ -102,6 +102,10 @@ return array(
 			'_' => 'המשתמש %s נמחק',
 			'error' => 'User %s cannot be deleted', // @todo
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => 'Your profile cannot be modified', // @todo

+ 1 - 0
app/i18n/he/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'ראו אתר',
 		'submit' => 'אישור',
 		'truncate' => 'מחיקת כל המאמרים',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Email address', // @todo

+ 3 - 0
app/i18n/it/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s articoli (%s)',
 		'create' => 'Crea nuovo utente',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'Lingua',
 		'number' => ' %d profilo utente creato',
 		'numbers' => 'Sono presenti %d profili utente',
 		'password_form' => 'Password<br /><small>(per il login classico)</small>',
 		'password_format' => 'Almeno 7 caratteri',
+		'selected' => 'Selected user', // TODO
 		'title' => 'Gestione utenti',
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'Lista utenti',
 		'username' => 'Nome utente',
 		'users' => 'Utenti',

+ 4 - 0
app/i18n/it/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'Utente %s cancellato',
 			'error' => 'Utente %s non cancellato',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => 'Il tuo profilo non può essere modificato',

+ 1 - 0
app/i18n/it/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'Vai al sito',
 		'submit' => 'Conferma',
 		'truncate' => 'Cancella tutti gli articoli',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Indirizzo email',

+ 3 - 0
app/i18n/kr/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s 개의 글 (%s)',
 		'create' => '새 사용자 생성',
+		'delete_users' => 'Delete user', // TODO
 		'language' => '언어',
 		'number' => '%d 개의 계정이 생성되었습니다',
 		'numbers' => '%d 개의 계정이 생성되었습니다',
 		'password_form' => '암호<br /><small>(웹폼 로그인 방식 사용시)</small>',
 		'password_format' => '7 글자 이상이어야 합니다',
+		'selected' => 'Selected user', // TODO
 		'title' => '사용자 관리',
+		'update_users' => 'Update user', // TODO
 		'user_list' => '사용자 목록',
 		'username' => '사용자 이름',
 		'users' => '전체 사용자',

+ 4 - 0
app/i18n/kr/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => '%s 사용자를 삭제했습니다',
 			'error' => '%s 사용자를 삭제할 수 없습니다',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => '프로필을 변경할 수 없습니다',

+ 1 - 0
app/i18n/kr/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => '웹사이트 열기',
 		'submit' => '설정 저장',
 		'truncate' => '모든 글 삭제',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => '메일 주소',

+ 3 - 0
app/i18n/nl/admin.php

@@ -175,6 +175,7 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s artikelen (%s)',
 		'create' => 'Creëer nieuwe gebruiker',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'Taal',
 		'number' => 'Er is %d accounts gemaakt',
 		'numbers' => 'Er zijn %d accounts gemaakt',
@@ -185,7 +186,9 @@ return array(
 			'help' => '0 betekent dat er geen accountlimiet is',
 			'number' => 'Max aantal accounts',
 		),
+		'selected' => 'Selected user', // TODO
 		'title' => 'Beheer gebruikers',
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'Lijst van gebruikers ',
 		'username' => 'Gebruikersnaam',
 		'users' => 'Gebruikers',

+ 4 - 0
app/i18n/nl/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'Gebruiker %s is verwijderd',
 			'error' => 'Gebruiker %s kan niet worden verwijderd',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 		'set_registration' => 'Het maximale aantal accounts is vernieuwd.',
 	),
 	'profile' => array(

+ 1 - 0
app/i18n/nl/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'Bekijk website',
 		'submit' => 'Opslaan',
 		'truncate' => 'Verwijder alle artikelen',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Email adres',

+ 3 - 0
app/i18n/pt-br/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s artigos (%s)',
 		'create' => 'Criar novo usuário',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'Idioma',
 		'number' => 'Há %d conta criada',
 		'numbers' => 'Há %d contas criadas',
 		'password_form' => 'Senha<br /><small>(para o login pelo método do formulário)</small>',
 		'password_format' => 'Ao menos 7 caracteres',
+		'selected' => 'Selected user', // TODO
 		'title' => 'Gerenciar usuários',
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'Lista de usuários',
 		'username' => 'Usuário',
 		'users' => 'Usuários',

+ 4 - 0
app/i18n/pt-br/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'Usuário %s foi deletado',
 			'error' => 'Usuário %s não pode ser deletado',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => 'Your profile cannot be modified',

+ 1 - 0
app/i18n/pt-br/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'Ver o site',
 		'submit' => 'Enviar',
 		'truncate' => 'Deletar todos os artigos',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Endereço de e-mail',

+ 3 - 0
app/i18n/ru/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s статей (%s)',
 		'create' => 'Создать нового пользователя',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'Язык',
 		'number' => 'На данный момент создан %d аккаунт',
 		'numbers' => 'На данный момент аккаунтов создано:  %d',
 		'password_form' => 'Пароль<br /><small>(для входа через Веб-форму)</small>',
 		'password_format' => 'Минимум 7 символов',
+		'selected' => 'Selected user', // TODO
 		'title' => 'Управление пользователями',
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'Список пользователей',
 		'username' => 'Имя пользователя',
 		'users' => 'Пользователи',

+ 4 - 0
app/i18n/ru/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => 'User %s has been deleted',	//TODO
 			'error' => 'User %s cannot be deleted',	//TODO
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => 'Your profile cannot be modified',	//TODO

+ 1 - 0
app/i18n/ru/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'See website',
 		'submit' => 'Submit',
 		'truncate' => 'Delete all articles',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Email address',

+ 3 - 0
app/i18n/tr/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s makale (%s)',
 		'create' => 'Yeni kullanıcı oluştur',
+		'delete_users' => 'Delete user', // TODO
 		'language' => 'Dil',
 		'number' => 'Oluşturulmuş %d hesap var',
 		'numbers' => 'Oluşturulmuş %d hesap var',
 		'password_form' => 'Şifre<br /><small>(Tarayıcı girişi için)</small>',
 		'password_format' => 'En az 7 karakter',
+		'selected' => 'Selected user', // TODO
 		'title' => 'Kullanıcıları yönet',
+		'update_users' => 'Update user', // TODO
 		'user_list' => 'Kullanıcı listesi',
 		'username' => 'Kullanıcı adı',
 		'users' => 'Kullanıcılar',

+ 4 - 0
app/i18n/tr/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => '%s kullanıcısı silindi',
 			'error' => '%s kullanıcısı silinemedi',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => 'Profiliniz düzenlenemedi',

+ 1 - 0
app/i18n/tr/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => 'Siteyi gör',
 		'submit' => 'Onayla',
 		'truncate' => 'Tüm makaleleri sil',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Email adresleri',

+ 3 - 0
app/i18n/zh-cn/admin.php

@@ -175,12 +175,15 @@ return array(
 	'user' => array(
 		'articles_and_size' => '%s 篇文章 (%s)',
 		'create' => '创建新用户',
+		'delete_users' => 'Delete user', // TODO
 		'language' => '语言',
 		'number' => '已有 %d 个帐户',
 		'numbers' => '已有 %d 个帐户',
 		'password_form' => '密码<br /><small>(用于 Web-form 登录方式)</small>',
 		'password_format' => '至少 7 个字符',
+		'selected' => 'Selected user', // TODO
 		'title' => '用户管理',
+		'update_users' => 'Update user', // TODO
 		'user_list' => '用户列表',
 		'username' => '用户名',
 		'users' => '用户',

+ 4 - 0
app/i18n/zh-cn/feedback.php

@@ -101,6 +101,10 @@ return array(
 			'_' => '用户 %s 已删除',
 			'error' => '用户 %s 删除失败',
 		),
+		'updated' => array(
+			'_' => 'User %s has been updated', // TODO
+			'error' => 'User %s has not been updated', // TODO
+		),
 	),
 	'profile' => array(
 		'error' => '你的帐户修改失败',

+ 1 - 0
app/i18n/zh-cn/gen.php

@@ -19,6 +19,7 @@ return array(
 		'see_website' => '查看网站',
 		'submit' => '提交',
 		'truncate' => '删除所有文章',
+		'update' => 'Update', // TODO
 	),
 	'auth' => array(
 		'email' => 'Email 地址',

+ 39 - 2
app/views/user/manage.phtml

@@ -46,14 +46,51 @@
 		</div>
 	</form>
 
+	<form method="post" action="<?php echo _url('user', 'update'); ?>">
+		<input type="hidden" name="_csrf" value="<?php echo FreshRSS_Auth::csrfToken(); ?>" />
+		<legend><?php echo _t('admin.user.update_users'); ?></legend>
+
+		<div class="form-group">
+			<label class="group-name" for="current_user"><?php echo _t('admin.user.selected'); ?></label>
+			<div class="group-controls">
+				<select id="current_user" class="select-change" name="username">
+					<option selected="selected"> </option>
+					<?php foreach (listUsers() as $username) { ?>
+					<option value="<?php echo $username; ?>"><?php echo $username; ?></option>
+					<?php } ?>
+				</select>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="newPasswordPlain"><?php echo _t('admin.user.password_form'); ?></label>
+			<div class="group-controls">
+				<div class="stick">
+					<input type="password" id="newPasswordPlain" name="newPasswordPlain" autocomplete="off" pattern=".{7,}" <?php echo cryptAvailable() ? '' : 'disabled="disabled" '; ?>/>
+					<a class="btn toggle-password" data-toggle="newPasswordPlain"><?php echo _i('key'); ?></a>
+				</div>
+				<?php echo _i('help'); ?> <?php echo _t('conf.profile.password_format'); ?>
+				<noscript><b><?php echo _t('gen.js.should_be_activated'); ?></b></noscript>
+			</div>
+		</div>
+
+		<div class="form-group form-actions">
+			<div class="group-controls">
+				<button type="submit" class="btn btn-important"><?php echo _t('gen.action.update'); ?></button>
+				<button type="reset" class="btn"><?php echo _t('gen.action.cancel'); ?></button>
+			</div>
+		</div>
+	</form>
+
 	<form method="post" action="<?php echo _url('user', 'delete'); ?>">
 		<input type="hidden" name="_csrf" value="<?php echo FreshRSS_Auth::csrfToken(); ?>" />
-		<legend><?php echo _t('admin.user.users'); ?></legend>
+		<legend><?php echo _t('admin.user.delete_users'); ?></legend>
 
 		<div class="form-group">
-			<label class="group-name" for="user-list"><?php echo _t('admin.user.user_list'); ?></label>
+			<label class="group-name" for="user-list"><?php echo _t('admin.user.selected'); ?></label>
 			<div class="group-controls">
 				<select id="user-list" class="select-change" name="username">
+					<option selected="selected"> </option>
 					<?php foreach (listUsers() as $username) { ?>
 					<option data-url="<?php echo _url('user', 'manage', 'u', $username); ?>" <?php echo $this->current_user === $username ? 'selected="selected"' : ''; ?> value="<?php echo $username; ?>"><?php echo $username; ?></option>
 					<?php } ?>

+ 2 - 1
cli/update-user.php

@@ -7,7 +7,8 @@ $username = cliInitUser($options['user']);
 
 echo 'FreshRSS updating user “', $username, "”…\n";
 
-$ok = FreshRSS_user_Controller::updateContextUser(
+$ok = FreshRSS_user_Controller::updateUser(
+	$username,
 	empty($options['password']) ? '' : $options['password'],
 	empty($options['api_password']) ? '' : $options['api_password'],
 	$values);