Skip to content

Commit 53d3903

Browse files
Merge pull request #51392 from nextcloud/backport/51320/stable29
[stable29] fix(external_storage): fix settings save
2 parents 703c60d + 0fa6a28 commit 53d3903

File tree

7 files changed

+82
-36
lines changed

7 files changed

+82
-36
lines changed

apps/files_external/lib/Controller/AjaxController.php

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131
use OCA\Files_External\Lib\Auth\Password\GlobalAuth;
3232
use OCA\Files_External\Lib\Auth\PublicKey\RSA;
3333
use OCP\AppFramework\Controller;
34+
use OCP\AppFramework\Http;
3435
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
3536
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
3637
use OCP\AppFramework\Http\JSONResponse;
3738
use OCP\IGroupManager;
39+
use OCP\IL10N;
3840
use OCP\IRequest;
3941
use OCP\IUserSession;
4042

@@ -47,6 +49,8 @@ class AjaxController extends Controller {
4749
private $userSession;
4850
/** @var IGroupManager */
4951
private $groupManager;
52+
/** @var IL10N */
53+
private $l10n;
5054

5155
/**
5256
* @param string $appName
@@ -61,12 +65,15 @@ public function __construct($appName,
6165
RSA $rsaMechanism,
6266
GlobalAuth $globalAuth,
6367
IUserSession $userSession,
64-
IGroupManager $groupManager) {
68+
IGroupManager $groupManager,
69+
IL10N $l10n,
70+
) {
6571
parent::__construct($appName, $request);
6672
$this->rsaMechanism = $rsaMechanism;
6773
$this->globalAuth = $globalAuth;
6874
$this->userSession = $userSession;
6975
$this->groupManager = $groupManager;
76+
$this->l10n = $l10n;
7077
}
7178

7279
/**
@@ -89,27 +96,30 @@ private function generateSshKeys($keyLength) {
8996
*/
9097
public function getSshKeys($keyLength = 1024) {
9198
$key = $this->generateSshKeys($keyLength);
92-
return new JSONResponse(
93-
['data' => [
99+
return new JSONResponse([
100+
'data' => [
94101
'private_key' => $key['privatekey'],
95102
'public_key' => $key['publickey']
96103
],
97-
'status' => 'success'
98-
]);
104+
'status' => 'success',
105+
]);
99106
}
100107

101108
/**
102109
* @param string $uid
103110
* @param string $user
104111
* @param string $password
105-
* @return bool
112+
* @return JSONResponse
106113
*/
107114
#[NoAdminRequired]
108115
#[PasswordConfirmationRequired(strict: true)]
109-
public function saveGlobalCredentials($uid, $user, $password) {
116+
public function saveGlobalCredentials($uid, $user, $password): JSONResponse {
110117
$currentUser = $this->userSession->getUser();
111118
if ($currentUser === null) {
112-
return false;
119+
return new JSONResponse([
120+
'status' => 'error',
121+
'message' => $this->l10n->t('You are not logged in'),
122+
], Http::STATUS_UNAUTHORIZED);
113123
}
114124

115125
// Non-admins can only edit their own credentials
@@ -120,9 +130,14 @@ public function saveGlobalCredentials($uid, $user, $password) {
120130

121131
if ($allowedToEdit) {
122132
$this->globalAuth->saveAuth($uid, $user, $password);
123-
return true;
133+
return new JSONResponse([
134+
'status' => 'success',
135+
]);
124136
}
125137

126-
return false;
138+
return new JSONResponse([
139+
'status' => 'success',
140+
'message' => $this->l10n->t('Permission denied'),
141+
], Http::STATUS_FORBIDDEN);
127142
}
128143
}

apps/files_external/src/settings.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
*
99
*/
1010

11-
import axios from '@nextcloud/axios'
12-
import { t } from '@nextcloud/l10n'
1311
import { addPasswordConfirmationInterceptors, PwdConfirmationMode } from '@nextcloud/password-confirmation'
12+
import { generateUrl } from '@nextcloud/router'
13+
import { showError } from '@nextcloud/dialogs'
14+
import { t } from '@nextcloud/l10n'
15+
import axios, { isAxiosError } from '@nextcloud/axios'
1416

1517
import jQuery from 'jquery'
1618

@@ -1526,21 +1528,30 @@ window.addEventListener('DOMContentLoaded', function() {
15261528
const uid = $form.find('[name=uid]').val()
15271529
const user = $form.find('[name=username]').val()
15281530
const password = $form.find('[name=password]').val()
1529-
await axios.request({
1530-
method: 'POST',
1531-
data: JSON.stringify({
1532-
uid,
1533-
user,
1534-
password,
1535-
}),
1536-
url: OC.generateUrl('apps/files_external/globalcredentials'),
1537-
confirmPassword: PwdConfirmationMode.Strict,
1538-
})
15391531

1540-
$submit.val(t('files_external', 'Saved'))
1541-
setTimeout(function() {
1532+
try {
1533+
await axios.request({
1534+
method: 'POST',
1535+
data: {
1536+
uid,
1537+
user,
1538+
password,
1539+
},
1540+
url: generateUrl('apps/files_external/globalcredentials'),
1541+
confirmPassword: PwdConfirmationMode.Strict,
1542+
})
1543+
1544+
$submit.val(t('files_external', 'Saved'))
1545+
setTimeout(function() {
1546+
$submit.val(t('files_external', 'Save'))
1547+
}, 2500)
1548+
} catch (error) {
15421549
$submit.val(t('files_external', 'Save'))
1543-
}, 2500)
1550+
if (isAxiosError(error)) {
1551+
const message = error.response?.data?.message || t('files_external', 'Failed to save global credentials')
1552+
showError(t('files_external', 'Failed to save global credentials: {message}', { message }))
1553+
}
1554+
}
15441555

15451556
return false
15461557
})

apps/files_external/tests/Controller/AjaxControllerTest.php

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use OCA\Files_External\Lib\Auth\PublicKey\RSA;
3030
use OCP\AppFramework\Http\JSONResponse;
3131
use OCP\IGroupManager;
32+
use OCP\IL10N;
3233
use OCP\IRequest;
3334
use OCP\IUser;
3435
use OCP\IUserSession;
@@ -47,6 +48,8 @@ class AjaxControllerTest extends TestCase {
4748
private $groupManager;
4849
/** @var AjaxController */
4950
private $ajaxController;
51+
/** @var IL10N */
52+
private $l10n;
5053

5154
protected function setUp(): void {
5255
$this->request = $this->createMock(IRequest::class);
@@ -58,16 +61,27 @@ protected function setUp(): void {
5861
->getMock();
5962
$this->userSession = $this->createMock(IUserSession::class);
6063
$this->groupManager = $this->createMock(IGroupManager::class);
64+
$this->l10n = $this->createMock(IL10N::class);
6165

6266
$this->ajaxController = new AjaxController(
6367
'files_external',
6468
$this->request,
6569
$this->rsa,
6670
$this->globalAuth,
6771
$this->userSession,
68-
$this->groupManager
72+
$this->groupManager,
73+
$this->l10n,
6974
);
7075

76+
$this->l10n->expects($this->any())
77+
->method('t')
78+
->willReturnCallback(function ($string, $args) {
79+
if (!is_array($args)) {
80+
$args = [$args];
81+
}
82+
return vsprintf($string, $args);
83+
});
84+
7185
parent::setUp();
7286
}
7387

@@ -106,7 +120,9 @@ public function testSaveGlobalCredentialsAsAdminForAnotherUser() {
106120
->expects($this->never())
107121
->method('saveAuth');
108122

109-
$this->assertSame(false, $this->ajaxController->saveGlobalCredentials('UidOfTestUser', 'test', 'password'));
123+
$response = $this->ajaxController->saveGlobalCredentials('UidOfTestUser', 'test', 'password');
124+
$this->assertSame($response->getStatus(), 403);
125+
$this->assertSame('Permission denied', $response->getData()['message']);
110126
}
111127

112128
public function testSaveGlobalCredentialsAsAdminForSelf() {
@@ -124,7 +140,8 @@ public function testSaveGlobalCredentialsAsAdminForSelf() {
124140
->method('saveAuth')
125141
->with('MyAdminUid', 'test', 'password');
126142

127-
$this->assertSame(true, $this->ajaxController->saveGlobalCredentials('MyAdminUid', 'test', 'password'));
143+
$response = $this->ajaxController->saveGlobalCredentials('MyAdminUid', 'test', 'password');
144+
$this->assertSame($response->getStatus(), 200);
128145
}
129146

130147
public function testSaveGlobalCredentialsAsNormalUserForSelf() {
@@ -139,7 +156,8 @@ public function testSaveGlobalCredentialsAsNormalUserForSelf() {
139156
->method('saveAuth')
140157
->with('MyUserUid', 'test', 'password');
141158

142-
$this->assertSame(true, $this->ajaxController->saveGlobalCredentials('MyUserUid', 'test', 'password'));
159+
$response = $this->ajaxController->saveGlobalCredentials('MyUserUid', 'test', 'password');
160+
$this->assertSame($response->getStatus(), 200);
143161
}
144162

145163
public function testSaveGlobalCredentialsAsNormalUserForAnotherUser() {
@@ -154,6 +172,8 @@ public function testSaveGlobalCredentialsAsNormalUserForAnotherUser() {
154172
->expects($this->never())
155173
->method('saveAuth');
156174

157-
$this->assertSame(false, $this->ajaxController->saveGlobalCredentials('AnotherUserUid', 'test', 'password'));
175+
$response = $this->ajaxController->saveGlobalCredentials('AnotherUserUid', 'test', 'password');
176+
$this->assertSame($response->getStatus(), 403);
177+
$this->assertSame('Permission denied', $response->getData()['message']);
158178
}
159179
}

dist/core-common.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/core-common.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/files_external-settings.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/files_external-settings.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)