aboutsummaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorRobin Appelman <icewind@owncloud.com>2016-01-19 14:16:11 +0100
committerRobin Appelman <icewind@owncloud.com>2016-01-29 14:51:30 +0100
commit860d51487b103f4c050d2427c35ee70dd4b2b05e (patch)
treea59988eaaba438fa2fa5dbb6ac574d81cc2fb047 /apps
parentf3e9729a5f68fa36ee6633955b7913f37e1c890e (diff)
downloadnextcloud-server-860d51487b103f4c050d2427c35ee70dd4b2b05e.tar.gz
nextcloud-server-860d51487b103f4c050d2427c35ee70dd4b2b05e.zip
Allow setting user provided credentials from the personal settings page
Diffstat (limited to 'apps')
-rw-r--r--apps/files_external/controller/storagescontroller.php2
-rw-r--r--apps/files_external/controller/usercredentialscontroller.php49
-rw-r--r--apps/files_external/controller/userstoragescontroller.php1
-rw-r--r--apps/files_external/js/settings.js115
-rw-r--r--apps/files_external/lib/auth/password/userprovided.php9
-rw-r--r--apps/files_external/lib/definitionparameter.php48
6 files changed, 180 insertions, 44 deletions
diff --git a/apps/files_external/controller/storagescontroller.php b/apps/files_external/controller/storagescontroller.php
index 64b989f0c77..b09774ef515 100644
--- a/apps/files_external/controller/storagescontroller.php
+++ b/apps/files_external/controller/storagescontroller.php
@@ -25,6 +25,7 @@ namespace OCA\Files_External\Controller;
use \OCP\IConfig;
+use OCP\IUser;
use \OCP\IUserSession;
use \OCP\IRequest;
use \OCP\IL10N;
@@ -114,6 +115,7 @@ abstract class StoragesController extends Controller {
$priority
);
} catch (\InvalidArgumentException $e) {
+ \OC::$server->getLogger()->logException($e);
return new DataResponse(
[
'message' => (string)$this->l10n->t('Invalid backend or authentication mechanism class')
diff --git a/apps/files_external/controller/usercredentialscontroller.php b/apps/files_external/controller/usercredentialscontroller.php
index bc514cba088..5153189d9c3 100644
--- a/apps/files_external/controller/usercredentialscontroller.php
+++ b/apps/files_external/controller/usercredentialscontroller.php
@@ -21,12 +21,19 @@
namespace OCA\Files_External\Controller;
+use OCA\Calendar\Sabre\Backend;
+use OCA\Files_External\Lib\Auth\AuthMechanism;
use OCA\Files_External\Lib\Auth\Password\UserProvided;
+use OCA\Files_external\Lib\StorageConfig;
+use OCA\Files_External\Service\UserGlobalStoragesService;
use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\IL10N;
use OCP\IRequest;
use OCP\IUserSession;
-class UserCredentialsController extends Controller {
+class UserCredentialsController extends StoragesController {
/**
* @var UserProvided
*/
@@ -37,10 +44,22 @@ class UserCredentialsController extends Controller {
*/
private $userSession;
- public function __construct($appName, IRequest $request, UserProvided $authMechanism, IUserSession $userSession) {
- parent::__construct($appName, $request);
+ /**
+ * @var UserGlobalStoragesService
+ */
+ private $globalStoragesService;
+
+ public function __construct(
+ $appName, IRequest $request,
+ UserProvided $authMechanism,
+ IUserSession $userSession,
+ IL10N $l10n,
+ UserGlobalStoragesService $globalStoragesService
+ ) {
+ parent::__construct($appName, $request, $l10n, $globalStoragesService);
$this->authMechanism = $authMechanism;
$this->userSession = $userSession;
+ $this->globalStoragesService = $globalStoragesService;
}
/**
@@ -49,8 +68,32 @@ class UserCredentialsController extends Controller {
* @param string $password
*
* @NoAdminRequired
+ * @return DataResponse
*/
public function store($storageId, $username, $password) {
$this->authMechanism->saveCredentials($this->userSession->getUser(), $storageId, $username, $password);
+
+ $storage = $this->globalStoragesService->getStorage($storageId);
+
+ $this->updateStorageStatus($storage);
+
+ $storage->setBackendOptions([]);
+ $storage->setMountOptions([]);
+ $this->manipulateStorageConfig($storage);
+
+
+ return new DataResponse(
+ $storage,
+ Http::STATUS_OK
+ );
+ }
+
+ protected function manipulateStorageConfig(StorageConfig $storage) {
+ /** @var AuthMechanism */
+ $authMechanism = $storage->getAuthMechanism();
+ $authMechanism->manipulateStorageConfig($storage, $this->userSession->getUser());
+ /** @var Backend */
+ $backend = $storage->getBackend();
+ $backend->manipulateStorageConfig($storage, $this->userSession->getUser());
}
}
diff --git a/apps/files_external/controller/userstoragescontroller.php b/apps/files_external/controller/userstoragescontroller.php
index 741e906dec1..ccf8bc24e09 100644
--- a/apps/files_external/controller/userstoragescontroller.php
+++ b/apps/files_external/controller/userstoragescontroller.php
@@ -25,6 +25,7 @@ namespace OCA\Files_External\Controller;
use OCA\Files_External\Lib\Auth\AuthMechanism;
use \OCP\IConfig;
+use OCP\IUser;
use \OCP\IUserSession;
use \OCP\IRequest;
use \OCP\IL10N;
diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js
index 756804238d0..16576ce7087 100644
--- a/apps/files_external/js/settings.js
+++ b/apps/files_external/js/settings.js
@@ -357,6 +357,9 @@ StorageConfig.prototype = {
if (this.mountPoint === '') {
return false;
}
+ if (!this.backend) {
+ return false;
+ }
if (this.errors) {
return false;
}
@@ -433,6 +436,48 @@ UserStorageConfig.prototype = _.extend({}, StorageConfig.prototype,
});
/**
+ * @class OCA.External.Settings.UserGlobalStorageConfig
+ * @augments OCA.External.Settings.StorageConfig
+ *
+ * @classdesc User external storage config
+ */
+var UserGlobalStorageConfig = function (id) {
+ this.id = id;
+};
+UserGlobalStorageConfig.prototype = _.extend({}, StorageConfig.prototype,
+ /** @lends OCA.External.Settings.UserStorageConfig.prototype */ {
+
+ _url: 'apps/files_external/userglobalstorages',
+
+ /**
+ * Creates or saves the storage.
+ *
+ * @param {Function} [options.success] success callback, receives result as argument
+ * @param {Function} [options.error] error callback
+ */
+ save: function (options) {
+ var self = this;
+ var url = OC.generateUrl('apps/files_external/usercredentials/{id}', {id: this.id});
+
+ $.ajax({
+ type: 'PUT',
+ url: url,
+ contentType: 'application/json',
+ data: JSON.stringify({
+ username: this.backendOptions.user,
+ password: this.backendOptions.password
+ }),
+ success: function (result) {
+ if (_.isFunction(options.success)) {
+ options.success(result);
+ }
+ },
+ error: options.error
+ });
+ }
+});
+
+/**
* @class OCA.External.Settings.MountOptionsDropdown
*
* @classdesc Dropdown for mount options
@@ -748,7 +793,7 @@ MountConfigListView.prototype = _.extend({
$.each(authMechanismConfiguration['configuration'], _.partial(
this.writeParameterInput, $td, _, _, ['auth-param']
- ));
+ ).bind(this));
this.trigger('selectAuthMechanism',
$tr, authMechanism, authMechanismConfiguration['scheme'], onCompletion
@@ -770,6 +815,7 @@ MountConfigListView.prototype = _.extend({
var $tr = this.$el.find('tr#addMountPoint');
this.$el.find('tbody').append($tr.clone());
+ $tr.data('storageConfig', storageConfig);
$tr.find('td').last().attr('class', 'remove');
$tr.find('td.mountOptionsToggle').removeClass('hidden');
$tr.find('td').last().removeAttr('style');
@@ -805,7 +851,7 @@ MountConfigListView.prototype = _.extend({
$tr.find('td.authentication').append(selectAuthMechanism);
var $td = $tr.find('td.configuration');
- $.each(backend.configuration, _.partial(this.writeParameterInput, $td));
+ $.each(backend.configuration, _.partial(this.writeParameterInput, $td).bind(this));
this.trigger('selectBackend', $tr, backend.identifier, onCompletion);
this.configureAuthMechanism($tr, storageConfig.authMechanism, onCompletion);
@@ -866,8 +912,14 @@ MountConfigListView.prototype = _.extend({
success: function(result) {
var onCompletion = jQuery.Deferred();
$.each(result, function(i, storageParams) {
+ var storageConfig;
+ var isUserProvidedAuth = storageParams.authMechanism === 'password::userprovided';
storageParams.mountPoint = storageParams.mountPoint.substr(1); // trim leading slash
- var storageConfig = new self._storageConfigClass();
+ if (isUserProvidedAuth) {
+ storageConfig = new UserGlobalStorageConfig();
+ } else {
+ storageConfig = new self._storageConfigClass();
+ }
_.extend(storageConfig, storageParams);
var $tr = self.newStorage(storageConfig, onCompletion);
@@ -878,12 +930,16 @@ MountConfigListView.prototype = _.extend({
var $authentication = $tr.find('.authentication');
$authentication.text($authentication.find('select option:selected').text());
- // userglobal storages do not expose configuration data
- $tr.find('.configuration').text(t('files_external', 'Admin defined'));
-
// disable any other inputs
$tr.find('.mountOptionsToggle, .remove').empty();
- $tr.find('input, select, button').attr('disabled', 'disabled');
+ $tr.find('input:not(.user_provided), select:not(.user_provided)').attr('disabled', 'disabled');
+
+ if (isUserProvidedAuth) {
+ $tr.find('.configuration').find(':not(.user_provided)').remove();
+ } else {
+ // userglobal storages do not expose configuration data
+ $tr.find('.configuration').text(t('files_external', 'Admin defined'));
+ }
});
onCompletion.resolve();
}
@@ -918,22 +974,40 @@ MountConfigListView.prototype = _.extend({
* @return {jQuery} newly created input
*/
writeParameterInput: function($td, parameter, placeholder, classes) {
+ var hasFlag = function(flag) {
+ return placeholder.indexOf(flag) !== -1;
+ };
classes = $.isArray(classes) ? classes : [];
classes.push('added');
if (placeholder.indexOf('&') === 0) {
classes.push('optional');
placeholder = placeholder.substring(1);
}
+
+ if (hasFlag('@')) {
+ if (this._isPersonal) {
+ classes.push('user_provided');
+ } else {
+ return;
+ }
+ }
+
var newElement;
- if (placeholder.indexOf('*') === 0) {
- newElement = $('<input type="password" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');
- } else if (placeholder.indexOf('!') === 0) {
+
+ var trimmedPlaceholder = placeholder;
+ var flags = ['@', '*', '!', '#', '&'];
+ while(flags.indexOf(trimmedPlaceholder[0]) !== -1) {
+ trimmedPlaceholder = trimmedPlaceholder.substr(1);
+ }
+ if (hasFlag('*')) {
+ newElement = $('<input type="password" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+ trimmedPlaceholder+'" />');
+ } else if (hasFlag('!')) {
var checkboxId = _.uniqueId('checkbox_');
- newElement = $('<input type="checkbox" id="'+checkboxId+'" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" /><label for="'+checkboxId+'">'+placeholder.substring(1)+'</label>');
- } else if (placeholder.indexOf('#') === 0) {
+ newElement = $('<input type="checkbox" id="'+checkboxId+'" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" /><label for="'+checkboxId+'">'+ trimmedPlaceholder+'</label>');
+ } else if (hasFlag('#')) {
newElement = $('<input type="hidden" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" />');
} else {
- newElement = $('<input type="text" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');
+ newElement = $('<input type="text" class="'+classes.join(' ')+'" data-parameter="'+parameter+'" placeholder="'+ trimmedPlaceholder+'" />');
}
highlightInput(newElement);
$td.append(newElement);
@@ -952,7 +1026,12 @@ MountConfigListView.prototype = _.extend({
// new entry
storageId = null;
}
- var storage = new this._storageConfigClass(storageId);
+
+ var storage = $tr.data('storageConfig');
+ if (!storage) {
+ storage = new this._storageConfigClass(storageId);
+ }
+ storage.errors = null;
storage.mountPoint = $tr.find('.mountPoint input').val();
storage.backend = $tr.find('.backend').data('identifier');
storage.authMechanism = $tr.find('.selectAuthMechanism').val();
@@ -966,7 +1045,7 @@ MountConfigListView.prototype = _.extend({
if ($input.attr('type') === 'button') {
return;
}
- if (!isInputValid($input)) {
+ if (!isInputValid($input) && !$input.hasClass('optional')) {
missingOptions.push(parameter);
return;
}
@@ -994,7 +1073,7 @@ MountConfigListView.prototype = _.extend({
var users = [];
var multiselect = getSelection($tr);
$.each(multiselect, function(index, value) {
- var pos = value.indexOf('(group)');
+ var pos = (value.indexOf)?value.indexOf('(group)'): -1;
if (pos !== -1) {
groups.push(value.substr(0, pos));
} else {
@@ -1057,7 +1136,9 @@ MountConfigListView.prototype = _.extend({
saveStorageConfig:function($tr, callback, concurrentTimer) {
var self = this;
var storage = this.getStorageConfig($tr);
- if (!storage.validate()) {
+ console.log(storage);
+ if (!storage || !storage.validate()) {
+ console.log('invalid');
return false;
}
diff --git a/apps/files_external/lib/auth/password/userprovided.php b/apps/files_external/lib/auth/password/userprovided.php
index 8854513e161..b0ff50a279a 100644
--- a/apps/files_external/lib/auth/password/userprovided.php
+++ b/apps/files_external/lib/auth/password/userprovided.php
@@ -21,6 +21,7 @@
namespace OCA\Files_External\Lib\Auth\Password;
+use OCA\Files_External\Lib\DefinitionParameter;
use OCP\IL10N;
use OCP\IUser;
use OCA\Files_External\Lib\Auth\AuthMechanism;
@@ -46,7 +47,13 @@ class UserProvided extends AuthMechanism {
->setIdentifier('password::userprovided')
->setScheme(self::SCHEME_PASSWORD)
->setText($l->t('User provided'))
- ->addParameters([]);
+ ->addParameters([
+ (new DefinitionParameter('user', $l->t('Username')))
+ ->setFlag(DefinitionParameter::FLAG_USER_PROVIDED),
+ (new DefinitionParameter('password', $l->t('Password')))
+ ->setType(DefinitionParameter::VALUE_PASSWORD)
+ ->setFlag(DefinitionParameter::FLAG_USER_PROVIDED),
+ ]);
}
private function getCredentialsIdentifier($storageId) {
diff --git a/apps/files_external/lib/definitionparameter.php b/apps/files_external/lib/definitionparameter.php
index 59a098e6320..85c3dd08ad4 100644
--- a/apps/files_external/lib/definitionparameter.php
+++ b/apps/files_external/lib/definitionparameter.php
@@ -35,6 +35,7 @@ class DefinitionParameter implements \JsonSerializable {
/** Flag constants */
const FLAG_NONE = 0;
const FLAG_OPTIONAL = 1;
+ const FLAG_USER_PROVIDED = 2;
/** @var string name of parameter */
private $name;
@@ -121,7 +122,7 @@ class DefinitionParameter implements \JsonSerializable {
* @return bool
*/
public function isFlagSet($flag) {
- return (bool) $this->flags & $flag;
+ return (bool)($this->flags & $flag);
}
/**
@@ -143,10 +144,11 @@ class DefinitionParameter implements \JsonSerializable {
break;
}
- switch ($this->getFlags()) {
- case self::FLAG_OPTIONAL:
- $prefix = '&' . $prefix;
- break;
+ if ($this->isFlagSet(self::FLAG_OPTIONAL)) {
+ $prefix = '&' . $prefix;
+ }
+ if ($this->isFlagSet(self::FLAG_USER_PROVIDED)) {
+ $prefix = '@' . $prefix;
}
return $prefix . $this->getText();
@@ -160,28 +162,28 @@ class DefinitionParameter implements \JsonSerializable {
* @return bool success
*/
public function validateValue(&$value) {
- $optional = $this->getFlags() & self::FLAG_OPTIONAL;
+ $optional = $this->isFlagSet(self::FLAG_OPTIONAL) || $this->isFlagSet(self::FLAG_USER_PROVIDED);
switch ($this->getType()) {
- case self::VALUE_BOOLEAN:
- if (!is_bool($value)) {
- switch ($value) {
- case 'true':
- $value = true;
- break;
- case 'false':
- $value = false;
- break;
- default:
+ case self::VALUE_BOOLEAN:
+ if (!is_bool($value)) {
+ switch ($value) {
+ case 'true':
+ $value = true;
+ break;
+ case 'false':
+ $value = false;
+ break;
+ default:
+ return false;
+ }
+ }
+ break;
+ default:
+ if (!$value && !$optional) {
return false;
}
- }
- break;
- default:
- if (!$value && !$optional) {
- return false;
- }
- break;
+ break;
}
return true;
}