Skip to content

Commit

Permalink
Add JSON column type
Browse files Browse the repository at this point in the history
  • Loading branch information
mrow4a committed Feb 3, 2019
1 parent 3b53864 commit 0d479c5
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 67 deletions.
2 changes: 2 additions & 0 deletions apps/files_sharing/lib/Controller/Share20OcsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,8 @@ private function setExtraPermissions($share, $formattedShareExtraPermissions) {
);
}
$share->setExtraPermissions($newShareExtraPermissions);
} else {
$share->setExtraPermissions(null);
}

return $share;
Expand Down
4 changes: 1 addition & 3 deletions core/Migrations/Version20181220085457.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@ class Version20181220085457 implements ISchemaMigration {
public function changeSchema(Schema $schema, array $options) {
$prefix = $options['tablePrefix'];

// FIXME: Should Type::TEXT or Type::JSON be used? For now use STRING
if ($schema->hasTable("${prefix}share")) {
$shareTable = $schema->getTable("${prefix}share");

if (!$shareTable->hasColumn('extra_permissions')) {
$shareTable->addColumn(
'extra_permissions',
Type::STRING,
Type::JSON,
[
'default' => null,
'length' => 4096,
'notnull' => false
]
);
Expand Down
27 changes: 19 additions & 8 deletions core/js/sharedialogshareelistview.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,31 @@
* @returns {object}
*/
getExtraPermissionsObject: function(shareIndex) {
var shareWith = this.model.getShareWith(shareIndex);
var model = this.model;
var shareWith = model.getShareWith(shareIndex);

// Returns OC.Share.Types.ShareExtraPermission[]
var permissions = this.model.getShareExtraPermissions(shareIndex);
var permissions = model.getShareExtraPermissions(shareIndex);

var list = [];
permissions.map(function(permission) {
list.push(_.extend(
{
var label = model.getShareExtraPermissionLabel(permission.app, permission.name);
if (label) {
list.push({
cid: this.cid,
shareWith: shareWith
},
permission)
);
shareWith: shareWith,
enabled: permission.enabled,
app: permission.app,
name: permission.name,
label: label
});
} else {
OC.Notification.showTemporary(t('core', 'Share with ' +
'user {shareWith} has permission {name} which became unavailable. ' +
'Please recreate the share!',
{ name: permission.name, shareWith: shareWith })
);
}
});

return list;
Expand Down
153 changes: 97 additions & 56 deletions core/js/shareitemmodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,20 @@
* @property {OC.Share.Types.LinkShareInfo|undefined} linkShare
*/

/**
* @typedef {object} OC.Share.Types.AvailableShareExtraPermission
* @property {string} name
* @property {bool} default
* @property {string} app
* @property {string} label
* @property {number[]} incompatiblePermissions
*/

/**
* @typedef {object} OC.Share.Types.ShareExtraPermission
* @property {string} name
* @property {bool} enabled
* @property {string} app
* @property {string} label
*/

/**
Expand Down Expand Up @@ -94,7 +102,7 @@
_linkSharesCollection: null,

/**
* @type {object} available extra permissions for this file/folder share
* @type {OC.Share.Types.AvailableShareExtraPermission[]} available extra permissions for this file/folder share
*/
_availableExtraPermissions: null,

Expand All @@ -108,7 +116,7 @@
}

this._linkSharesCollection = new OC.Share.SharesCollection();
this._availableExtraPermissions = JSON.parse('{}');
this._availableExtraPermissions = [];

_.bindAll(this, 'addShare');
OC.Plugins.attach('OC.Share.ShareItemModel', this);
Expand Down Expand Up @@ -160,12 +168,14 @@
}
attributes.permissions = defaultPermissions & possiblePermissions;

// set default allowed extra permissions for this share
var extraPermissions = [];
_.map(this._getCompatibleExtraPermissions(attributes.permissions), function(extraPermission) {
var allowedExtraPermissions = this._getAllowedExtraPermissions(attributes.permissions);
_.map(allowedExtraPermissions, function(extraPermission) {
extraPermissions.push({
app : extraPermission.app,
name: extraPermission.id,
enabled: extraPermission.meta.default
name: extraPermission.name,
enabled: extraPermission.default
});
});
attributes.extraPermissions = extraPermissions;
Expand Down Expand Up @@ -204,6 +214,35 @@
updateShare: function(shareId, attrs, options) {
var self = this;
options = options || {};

var extraPermissions = [];
var compatibleExtraPermissions = this._getAllowedExtraPermissions(attrs.permissions);
compatibleExtraPermissions.map(function(allowedExtraPermission) {
// Check existing extra permissions which are compatible
var found = false;
attrs.extraPermissions.map(function(currentExtraPermission) {
if (currentExtraPermission.name === allowedExtraPermission.name
&& currentExtraPermission.app === allowedExtraPermission.app) {
found = true;
extraPermissions.push({
app : currentExtraPermission.app,
name: currentExtraPermission.name,
enabled: currentExtraPermission.enabled
});
}
});

// if new permissions became available, set default
if (!found) {
extraPermissions.push({
app : allowedExtraPermission.app,
name: allowedExtraPermission.name,
enabled: allowedExtraPermission.default
});
}
});
attrs.extraPermissions = extraPermissions;

return $.ajax({
type: 'PUT',
url: this._getUrl('shares/' + encodeURIComponent(shareId)),
Expand Down Expand Up @@ -796,35 +835,23 @@
* extra permissions which are compatible
*
* @param {number} permissions
* @returns {Array}
* @returns {OC.Share.Types.AvailableShareExtraPermission[]}
* @private
*/
_getCompatibleExtraPermissions: function(permissions) {
_getAllowedExtraPermissions: function(permissions) {
var result = [];
for (var appId in this._availableExtraPermissions) {
if (!this._availableExtraPermissions.hasOwnProperty(appId)) {
continue;
}
for (var permissionId in this._availableExtraPermissions[appId]) {
if (!this._availableExtraPermissions[appId].hasOwnProperty(permissionId)) {
continue;
}
var permissionMeta = this._availableExtraPermissions[appId][permissionId];

var compatible = true;

for (var i in permissionMeta.incompatiblePermissions) {
if (this._hasPermission(permissions, permissionMeta.incompatiblePermissions[i])) {
compatible = false;
}
for(var i in this._availableExtraPermissions) {
var compatible = true;
var availPerm = this._availableExtraPermissions[i];
for(var j in availPerm.incompatiblePermissions) {
if (this._hasPermission(permissions, availPerm.incompatiblePermissions[j])) {
compatible = false;
}
}

if (compatible) {
result.push({
app: appId,
id: permissionId,
meta: permissionMeta
}); }
if (compatible) {
result.push(availPerm);
}
}

Expand All @@ -849,30 +876,30 @@
return [];
}

// Mark available permissions as enabled if share has extra permission
var formattedPermissions = [];
var shareExtraPermissions = JSON.parse(share.extra_permissions);
_.map(this._getCompatibleExtraPermissions(share.permissions), function(extraPermission) {
var enabled = extraPermission.meta.default;
if (shareExtraPermission) {
shareExtraPermissions.map(function(permission) {
if (permission.app === extraPermission.app &&
permission.name === extraPermission.id) {
enabled = permission.enabled;
}
});
}

var shareExtraPermission = {
app: extraPermission.app,
name: extraPermission.id,
label: extraPermission.meta.label,
enabled: enabled
};
formattedPermissions.push(shareExtraPermission);
});
// Add extra permissions for this share
var currentExtraPermissions = JSON.parse(share.extra_permissions);
if (currentExtraPermissions) {
return currentExtraPermissions;
}
return [];
},

return formattedPermissions;
/**
* Returns extra share permission label for given perm app and name. If
* extra permission does not exist, null is returned.
*
* @param app
* @param name
* @returns string|null
*/
getShareExtraPermissionLabel: function(app, name) {
for(var i in this._availableExtraPermissions) {
if (this._availableExtraPermissions[i].app === app
&& this._availableExtraPermissions[i].name === name) {
return this._availableExtraPermissions[i].label;
}
}
return null;
},

/**
Expand All @@ -885,14 +912,28 @@
* @param {number[]} $incompatiblePermissions
*/
registerExtraSharePermission: function($appId, $permissionName, $permissionLabel, $permissionDefault, $incompatiblePermissions) {
if (!this._availableExtraPermissions.hasOwnProperty($appId)) {
this._availableExtraPermissions[$appId] = {};
}
this._availableExtraPermissions[$appId][$permissionName] = {
/** @type OC.Share.Types.AvailableShareExtraPermission */
var extraPermission = {
app: $appId,
name: $permissionName,
incompatiblePermissions: $incompatiblePermissions,
default: $permissionDefault,
label: $permissionLabel
};

// Add extra permission or update if already existing
var exists = false;
for(var i in this._availableExtraPermissions) {
if (this._availableExtraPermissions[i].app === $appId
&& this._availableExtraPermissions[i].name === $permissionName) {
this._availableExtraPermissions[i] = extraPermission;
exists = true;
}
}
if (!exists) {
this._availableExtraPermissions.push(extraPermission);
}

}

});
Expand Down
2 changes: 2 additions & 0 deletions lib/private/Share20/DefaultShareProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,7 @@ private function validate($share) {
private function setExtraPermissions($share, $data) {
if ($data !== null) {
$extraPermissions = new ExtraPermissions();
// FIXME: add support for JSON in Doctrine
$extraPermissionsJson = \json_decode($data, true);
foreach ($extraPermissionsJson as $app => $keys) {
foreach ($keys as $key => $enabled) {
Expand Down Expand Up @@ -1303,6 +1304,7 @@ private function formatExtraPermissions($permissions) {
}
}

// FIXME: add support for JSON in Doctrine
return \json_encode($formattedPermissions);
}
}

0 comments on commit 0d479c5

Please sign in to comment.