From 98c933417583c9a83360a0a3c703867b2c32b940 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Thu, 14 Nov 2013 18:29:18 +0100
Subject: [PATCH 01/47] LDAP Wizard: move raw login filter field from advanced
tab to login filter tab for consistency
---
apps/user_ldap/js/settings.js | 19 +++++++++++++++++++
.../templates/part.wizard-loginfilter.php | 10 ++++++++++
apps/user_ldap/templates/settings.php | 3 ---
3 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js
index dcaeb70b57..4b219ee208 100644
--- a/apps/user_ldap/js/settings.js
+++ b/apps/user_ldap/js/settings.js
@@ -613,6 +613,8 @@ var LdapWizard = {
},
toggleRawFilter: function(container, moc, mg, stateVar) {
+ //moc = multiselect objectclass
+ //mg = mutliselect groups
if($(container).hasClass('invisible')) {
$(container).removeClass('invisible');
$(moc).multiselect('disable');
@@ -637,6 +639,22 @@ var LdapWizard = {
);
},
+ toggleRawLoginFilter: function() {
+ container = '#rawLoginFilterContainer';
+ if($(container).hasClass('invisible')) {
+ $(container).removeClass('invisible');
+ action = 'disable';
+ property = 'disabled';
+ } else {
+ $(container).addClass('invisible');
+ action = 'enable';
+ property = false;
+ }
+ $('#ldap_loginfilter_attributes').multiselect(action);
+ $('#ldap_loginfilter_email').prop('disabled', property);
+ $('#ldap_loginfilter_username').prop('disabled', property);
+ },
+
toggleRawUserFilter: function() {
LdapWizard.toggleRawFilter('#rawUserFilterContainer',
'#ldap_userfilter_objectclass',
@@ -670,6 +688,7 @@ $(document).ready(function() {
$('.lwautosave').change(function() { LdapWizard.save(this); });
$('#toggleRawUserFilter').click(LdapWizard.toggleRawUserFilter);
$('#toggleRawGroupFilter').click(LdapWizard.toggleRawGroupFilter);
+ $('#toggleRawLoginFilter').click(LdapWizard.toggleRawLoginFilter);
LdapConfiguration.refreshConfig();
$('.ldap_action_continue').click(function(event) {
event.preventDefault();
diff --git a/apps/user_ldap/templates/part.wizard-loginfilter.php b/apps/user_ldap/templates/part.wizard-loginfilter.php
index d4a36eb0cb..dc5d61e9f7 100644
--- a/apps/user_ldap/templates/part.wizard-loginfilter.php
+++ b/apps/user_ldap/templates/part.wizard-loginfilter.php
@@ -28,6 +28,16 @@
name="ldap_loginfilter_attributes">
+
+ ↓ t('Edit raw filter instead'));?>
+
+
+ "
+ />
+
diff --git a/apps/user_ldap/templates/settings.php b/apps/user_ldap/templates/settings.php
index feb5ac6385..3ccc7a860f 100644
--- a/apps/user_ldap/templates/settings.php
+++ b/apps/user_ldap/templates/settings.php
@@ -20,9 +20,6 @@
t('Connection Settings'));?>
t('Configuration Active'));?>
-
t('User Login Filter'));?> " />
t('Backup (Replica) Host'));?>
t('Backup (Replica) Port'));?>
t('Disable Main Server'));?>
From ff9ecc8a5197138726eb2a756c70399afb5eb97e Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Tue, 19 Nov 2013 23:58:08 +0100
Subject: [PATCH 02/47] LDAP Wizard: proper behaviour for raw filter input.
remember the editing mode and compose filter only when desired.
---
apps/user_ldap/ajax/wizard.php | 3 +
apps/user_ldap/js/settings.js | 139 +++++++++++++++++++++------
apps/user_ldap/lib/configuration.php | 9 ++
apps/user_ldap/lib/wizard.php | 39 ++++++++
4 files changed, 163 insertions(+), 27 deletions(-)
diff --git a/apps/user_ldap/ajax/wizard.php b/apps/user_ldap/ajax/wizard.php
index e580c09786..daad007011 100644
--- a/apps/user_ldap/ajax/wizard.php
+++ b/apps/user_ldap/ajax/wizard.php
@@ -53,8 +53,11 @@ switch($action) {
case 'determineGroupsForGroups':
case 'determineAttributes':
case 'getUserListFilter':
+ case 'getLoginFilterMode':
case 'getUserLoginFilter':
+ case 'getUserFilterMode':
case 'getGroupFilter':
+ case 'getGroupFilterMode':
case 'countUsers':
case 'countGroups':
try {
diff --git a/apps/user_ldap/js/settings.js b/apps/user_ldap/js/settings.js
index 4b219ee208..9d824a9e7e 100644
--- a/apps/user_ldap/js/settings.js
+++ b/apps/user_ldap/js/settings.js
@@ -106,7 +106,7 @@ var LdapConfiguration = {
clearMappings: function(mappingSubject) {
$.post(
OC.filePath('user_ldap','ajax','clearMappings.php'),
- 'ldap_clear_mapping='+mappingSubject,
+ 'ldap_clear_mapping='+encodeURIComponent(mappingSubject),
function(result) {
if(result.status == 'success') {
OC.dialogs.info(
@@ -129,6 +129,8 @@ var LdapWizard = {
saveBlacklist: {},
userFilterGroupSelectState: 'enable',
spinner: ' ',
+ filterModeAssisted: 0,
+ filterModeRaw: 1,
ajax: function(param, fnOnSuccess, fnOnError) {
$.post(
@@ -146,10 +148,7 @@ var LdapWizard = {
applyChanges: function (result) {
for (id in result.changes) {
- if(!$.isArray(result.changes[id])) {
- //no need to blacklist multiselect
- LdapWizard.saveBlacklist[id] = true;
- }
+ LdapWizard.blacklistAdd(id);
if(id.indexOf('count') > 0) {
$('#'+id).text(result.changes[id]);
} else {
@@ -181,6 +180,25 @@ var LdapWizard = {
}
},
+
+ blacklistAdd: function(id) {
+ obj = $('#'+id);
+ if(!(obj[0].hasOwnProperty('multiple') && obj[0]['multiple'] == true)) {
+ //no need to blacklist multiselect
+ LdapWizard.saveBlacklist[id] = true;
+ return true;
+ }
+ return false;
+ },
+
+ blacklistRemove: function(id) {
+ if(LdapWizard.saveBlacklist.hasOwnProperty(id)) {
+ delete LdapWizard.saveBlacklist[id];
+ return true;
+ }
+ return false;
+ },
+
checkBaseDN: function() {
host = $('#ldap_host').val();
port = $('#ldap_port').val();
@@ -189,7 +207,8 @@ var LdapWizard = {
if(host && port && user && pass) {
param = 'action=guessBaseDN'+
- '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.showSpinner('#ldap_base');
$('#ldap_base').prop('disabled', 'disabled');
@@ -217,7 +236,8 @@ var LdapWizard = {
if(host && !port) {
param = 'action=guessPortAndTLS'+
- '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.showSpinner('#ldap_port');
$('#ldap_port').prop('disabled', 'disabled');
@@ -241,6 +261,12 @@ var LdapWizard = {
},
composeFilter: function(type) {
+ subject = type.charAt(0).toUpperCase() + type.substr(1);
+ if(!$('#raw'+subject+'FilterContainer').hasClass('invisible')) {
+ //Raw filter editing, i.e. user defined filter, don't compose
+ return;
+ }
+
if(type == 'user') {
action = 'getUserListFilter';
} else if(type == 'login') {
@@ -250,7 +276,8 @@ var LdapWizard = {
}
param = 'action='+action+
- '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.ajax(param,
function(result) {
@@ -308,7 +335,8 @@ var LdapWizard = {
_countThings: function(method) {
param = 'action='+method+
- '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.ajax(param,
function(result) {
@@ -330,7 +358,8 @@ var LdapWizard = {
detectGroupMemberAssoc: function() {
param = 'action=determineGroupMemberAssoc'+
- '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.ajax(param,
function(result) {
@@ -344,7 +373,8 @@ var LdapWizard = {
findAttributes: function() {
param = 'action=determineAttributes'+
- '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.showSpinner('#ldap_loginfilter_attributes');
LdapWizard.ajax(param,
@@ -359,7 +389,9 @@ var LdapWizard = {
LdapWizard.hideSpinner('#ldap_loginfilter_attributes');
LdapWizard.applyChanges(result);
$('#ldap_loginfilter_attributes').multiselect('refresh');
- $('#ldap_loginfilter_attributes').multiselect('enable');
+ if($('#rawLoginFilterContainer').hasClass('invisible')) {
+ $('#ldap_loginfilter_attributes').multiselect('enable');
+ }
},
function (result) {
//deactivate if no attributes found
@@ -375,8 +407,9 @@ var LdapWizard = {
if(type != 'Users' && type != 'Groups') {
return false;
}
- param = 'action=determineGroupsFor'+type+
- '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+ param = 'action=determineGroupsFor'+encodeURIComponent(type)+
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.showSpinner('#'+multisel);
LdapWizard.ajax(param,
@@ -390,7 +423,11 @@ var LdapWizard = {
LdapWizard.hideSpinner('#'+multisel);
LdapWizard.applyChanges(result);
$('#'+multisel).multiselect('refresh');
- $('#'+multisel).multiselect('enable');
+ part = type.slice(0, -1);
+ if($('#raw' + part + 'FilterContainer').hasClass('invisible')) {
+ //enable only when raw filter editing is not turned on
+ $('#'+multisel).multiselect('enable');
+ }
},
function (result) {
LdapWizard.hideSpinner('#'+multisel);
@@ -403,8 +440,9 @@ var LdapWizard = {
if(type != 'User' && type != 'Group') {
return false;
}
- param = 'action=determine'+type+'ObjectClasses'+
- '&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
+ param = 'action=determine'+encodeURIComponent(type)+'ObjectClasses'+
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
LdapWizard.showSpinner('#'+multisel);
LdapWizard.ajax(param,
@@ -466,15 +504,15 @@ var LdapWizard = {
},
initGroupFilter: function() {
+ LdapWizard.regardFilterMode('Group');
LdapWizard.findObjectClasses('ldap_groupfilter_objectclass', 'Group');
LdapWizard.findAvailableGroups('ldap_groupfilter_groups', 'Groups');
- LdapWizard.composeFilter('group');
LdapWizard.countGroups();
},
initLoginFilter: function() {
+ LdapWizard.regardFilterMode('Login');
LdapWizard.findAttributes();
- LdapWizard.composeFilter('login');
},
initMultiSelect: function(object, id, caption) {
@@ -490,9 +528,9 @@ var LdapWizard = {
},
initUserFilter: function() {
+ LdapWizard.regardFilterMode('User');
LdapWizard.findObjectClasses('ldap_userfilter_objectclass', 'User');
LdapWizard.findAvailableGroups('ldap_userfilter_groups', 'Users');
- LdapWizard.composeFilter('user');
LdapWizard.countUsers();
},
@@ -546,9 +584,36 @@ var LdapWizard = {
}
},
+ regardFilterMode: function(subject) {
+ param = 'action=get'+encodeURIComponent(subject)+'FilterMode'+
+ '&ldap_serverconfig_chooser='+
+ encodeURIComponent($('#ldap_serverconfig_chooser').val());
+
+ LdapWizard.ajax(param,
+ function(result) {
+ property = 'ldap' + subject + 'FilterMode';
+ mode = result.changes[property];
+ if(mode == LdapWizard.filterModeRaw
+ && $('#raw'+subject+'FilterContainer').hasClass('invisible')) {
+ LdapWizard['toggleRaw'+subject+'Filter']();
+ } else if(mode == LdapWizard.filterModeAssisted
+ && !$('#raw'+subject+'FilterContainer').hasClass('invisible')) {
+ LdapWizard['toggleRaw'+subject+'Filter']();
+ } else {
+ c = $('#raw'+subject+'FilterContainer').hasClass('invisible');
+ }
+ },
+ function (result) {
+ //on error case get back to default i.e. Assisted
+ if(!$('#raw'+subject+'FilterContainer').hasClass('invisible')) {
+ LdapWizard['toggleRaw'+subject+'Filter']();
+ }
+ }
+ );
+ },
+
save: function(inputObj) {
- if(LdapWizard.saveBlacklist.hasOwnProperty(inputObj.id)) {
- delete LdapWizard.saveBlacklist[inputObj.id];
+ if(LdapWizard.blacklistRemove(inputObj.id)) {
return;
}
if($(inputObj).is('input[type=checkbox]')
@@ -581,8 +646,8 @@ var LdapWizard = {
},
_save: function(object, value) {
- param = 'cfgkey='+object.id+
- '&cfgval='+value+
+ param = 'cfgkey='+encodeURIComponent(object.id)+
+ '&cfgval='+encodeURIComponent(value)+
'&action=save'+
'&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
@@ -612,7 +677,7 @@ var LdapWizard = {
}
},
- toggleRawFilter: function(container, moc, mg, stateVar) {
+ toggleRawFilter: function(container, moc, mg, stateVar, modeKey) {
//moc = multiselect objectclass
//mg = mutliselect groups
if($(container).hasClass('invisible')) {
@@ -624,42 +689,62 @@ var LdapWizard = {
LdapWizard[stateVar] = 'enable';
}
$(mg).multiselect('disable');
+ LdapWizard._save({ id: modeKey }, LdapWizard.filterModeRaw);
} else {
$(container).addClass('invisible');
$(mg).multiselect(LdapWizard[stateVar]);
$(moc).multiselect('enable');
+ LdapWizard._save({ id: modeKey }, LdapWizard.filterModeAssisted);
+ if(moc.indexOf('user') >= 0) {
+ LdapWizard.blacklistRemove('ldap_userlist_filter');
+ LdapWizard.composeFilter('user');
+ } else {
+ LdapWizard.blacklistRemove('ldap_group_filter');
+ LdapWizard.composeFilter('group');
+ }
}
},
toggleRawGroupFilter: function() {
+ LdapWizard.blacklistRemove('ldap_group_filter');
LdapWizard.toggleRawFilter('#rawGroupFilterContainer',
'#ldap_groupfilter_objectclass',
'#ldap_groupfilter_groups',
- 'groupFilterGroupSelectState'
+ 'groupFilterGroupSelectState',
+ 'ldapGroupFilterMode'
);
},
toggleRawLoginFilter: function() {
+ LdapWizard.blacklistRemove('ldap_login_filter');
container = '#rawLoginFilterContainer';
if($(container).hasClass('invisible')) {
$(container).removeClass('invisible');
action = 'disable';
property = 'disabled';
+ mode = LdapWizard.filterModeRaw;
} else {
$(container).addClass('invisible');
action = 'enable';
property = false;
+ mode = LdapWizard.filterModeAssisted;
}
$('#ldap_loginfilter_attributes').multiselect(action);
$('#ldap_loginfilter_email').prop('disabled', property);
$('#ldap_loginfilter_username').prop('disabled', property);
+ LdapWizard._save({ id: 'ldapLoginFilterMode' }, mode);
+ if(action == 'enable') {
+ LdapWizard.composeFilter('login');
+ }
},
toggleRawUserFilter: function() {
+ LdapWizard.blacklistRemove('ldap_userlist_filter');
LdapWizard.toggleRawFilter('#rawUserFilterContainer',
'#ldap_userfilter_objectclass',
'#ldap_userfilter_groups',
- 'userFilterGroupSelectState'
+ 'userFilterGroupSelectState',
+ 'ldapUserFilterMode'
);
}
};
diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php
index e14ed824a7..b85cdfe25d 100644
--- a/apps/user_ldap/lib/configuration.php
+++ b/apps/user_ldap/lib/configuration.php
@@ -47,12 +47,15 @@ class Configuration {
'ldapUserFilterObjectclass' => null,
'ldapUserFilterGroups' => null,
'ldapUserFilter' => null,
+ 'ldapUserFilterMode' => null,
'ldapGroupFilter' => null,
+ 'ldapGroupFilterMode' => null,
'ldapGroupFilterObjectclass' => null,
'ldapGroupFilterGroups' => null,
'ldapGroupDisplayName' => null,
'ldapGroupMemberAssocAttr' => null,
'ldapLoginFilter' => null,
+ 'ldapLoginFilterMode' => null,
'ldapLoginFilterEmail' => null,
'ldapLoginFilterUsername' => null,
'ldapLoginFilterAttributes' => null,
@@ -301,13 +304,16 @@ class Configuration {
'ldap_base_users' => '',
'ldap_base_groups' => '',
'ldap_userlist_filter' => '',
+ 'ldap_user_filter_mode' => 0,
'ldap_userfilter_objectclass' => '',
'ldap_userfilter_groups' => '',
'ldap_login_filter' => 'uid=%uid',
+ 'ldap_login_filter_mode' => 0,
'ldap_loginfilter_email' => 0,
'ldap_loginfilter_username' => 1,
'ldap_loginfilter_attributes' => '',
'ldap_group_filter' => '',
+ 'ldap_group_filter_mode' => 0,
'ldap_groupfilter_objectclass' => '',
'ldap_groupfilter_groups' => '',
'ldap_display_name' => 'displayName',
@@ -352,11 +358,14 @@ class Configuration {
'ldap_userfilter_objectclass' => 'ldapUserFilterObjectclass',
'ldap_userfilter_groups' => 'ldapUserFilterGroups',
'ldap_userlist_filter' => 'ldapUserFilter',
+ 'ldap_user_filter_mode' => 'ldapUserFilterMode',
'ldap_login_filter' => 'ldapLoginFilter',
+ 'ldap_login_filter_mode' => 'ldapLoginFilterMode',
'ldap_loginfilter_email' => 'ldapLoginFilterEmail',
'ldap_loginfilter_username' => 'ldapLoginFilterUsername',
'ldap_loginfilter_attributes' => 'ldapLoginFilterAttributes',
'ldap_group_filter' => 'ldapGroupFilter',
+ 'ldap_group_filter_mode' => 'ldapGroupFilterMode',
'ldap_groupfilter_objectclass' => 'ldapGroupFilterObjectclass',
'ldap_groupfilter_groups' => 'ldapGroupFilterGroups',
'ldap_display_name' => 'ldapUserDisplayName',
diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php
index 0b2a6a540f..aac80f982a 100644
--- a/apps/user_ldap/lib/wizard.php
+++ b/apps/user_ldap/lib/wizard.php
@@ -38,6 +38,9 @@ class Wizard extends LDAPUtility {
const LFILTER_USER_LIST = 3;
const LFILTER_GROUP_LIST = 4;
+ const LFILTER_MODE_ASSISTED = 2;
+ const LFILTER_MODE_RAW = 1;
+
const LDAP_NW_TIMEOUT = 4;
/**
@@ -147,6 +150,42 @@ class Wizard extends LDAPUtility {
return $this->result;
}
+ /**
+ * @brief return the state of the Group Filter Mode
+ */
+ public function getGroupFilterMode() {
+ $this->getFilterMode('ldapGroupFilterMode');
+ return $this->result;
+ }
+
+ /**
+ * @brief return the state of the Login Filter Mode
+ */
+ public function getLoginFilterMode() {
+ $this->getFilterMode('ldapLoginFilterMode');
+ return $this->result;
+ }
+
+ /**
+ * @brief return the state of the User Filter Mode
+ */
+ public function getUserFilterMode() {
+ $this->getFilterMode('ldapUserFilterMode');
+ return $this->result;
+ }
+
+ /**
+ * @brief return the state of the mode of the specified filter
+ * @param $confkey string, contains the access key of the Configuration
+ */
+ private function getFilterMode($confkey) {
+ $mode = $this->configuration->$confkey;
+ if(is_null($mode)) {
+ $mode = $this->LFILTER_MODE_ASSISTED;
+ }
+ $this->result->addChange($confkey, $mode);
+ }
+
/**
* @brief detects the available LDAP attributes
* @returns the instance's WizardResult instance
From ce1318c9f109296fcdf7365178a96bc5de82e35a Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Wed, 20 Nov 2013 15:56:25 +0100
Subject: [PATCH 03/47] LDAP Wizard: clear the cache on save so changes have
immediate effect
---
apps/user_ldap/ajax/wizard.php | 3 +++
1 file changed, 3 insertions(+)
diff --git a/apps/user_ldap/ajax/wizard.php b/apps/user_ldap/ajax/wizard.php
index daad007011..ad75a38436 100644
--- a/apps/user_ldap/ajax/wizard.php
+++ b/apps/user_ldap/ajax/wizard.php
@@ -90,6 +90,9 @@ switch($action) {
exit;
}
$configuration->saveConfiguration();
+ //clear the cache on save
+ $connection = new \OCA\user_ldap\lib\Connection($ldapWrapper, $prefix);
+ $connection->clearCache();
OCP\JSON::success();
break;
default:
From c5cb4206f53d2a87f3d8e17fd8447dae4dc4a50c Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Wed, 20 Nov 2013 18:10:56 +0100
Subject: [PATCH 04/47] [wip] make encryption work with public gallery sharing
---
apps/files_encryption/lib/helper.php | 34 +++++++++++--
apps/files_encryption/lib/keymanager.php | 12 ++---
apps/files_encryption/lib/proxy.php | 7 +--
apps/files_encryption/lib/stream.php | 6 ++-
apps/files_encryption/lib/util.php | 62 +++++++++---------------
5 files changed, 65 insertions(+), 56 deletions(-)
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index 0ac6fcf403..e66a84d909 100755
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -225,10 +225,7 @@ class Helper {
* @return bool
*/
public static function isPublicAccess() {
- if (\OCP\USER::getUser() === false
- || (isset($_GET['service']) && $_GET['service'] == 'files'
- && isset($_GET['t']))
- ) {
+ if (\OCP\USER::getUser() === false) {
return true;
} else {
return false;
@@ -255,6 +252,35 @@ class Helper {
return $relPath;
}
+ public static function getUser($path) {
+
+ $user = \OCP\User::getUser();
+
+ // if we are logged in, than we return the userid
+ if ($user) {
+ return $user;
+ }
+
+ // if no user is logged in we try to access a publically shared files.
+ // In this case we need to try to get the user from the path
+
+ $trimmed = ltrim($path, '/');
+ $split = explode('/', $trimmed);
+
+ // it is not a file relative to data/user/files
+ if (count($split) < 2 || $split[1] !== 'files') {
+ return false;
+ }
+
+ $user = $split[0];
+
+ if (\OCP\User::userExists($user)) {
+ return $user;
+ }
+
+ return false;
+ }
+
/**
* @brief get path to the correspondig file in data/user/files if path points
* to a version or to a file in cache
diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php
index 6dadd12a62..8d3e72b422 100755
--- a/apps/files_encryption/lib/keymanager.php
+++ b/apps/files_encryption/lib/keymanager.php
@@ -172,16 +172,14 @@ class Keymanager {
/**
* @brief retrieve keyfile for an encrypted file
* @param \OC_FilesystemView $view
- * @param $userId
+ * @param \OCA\Encryption\Util $util
* @param $filePath
* @internal param \OCA\Encryption\file $string name
* @return string file key or false
* @note The keyfile returned is asymmetrically encrypted. Decryption
* of the keyfile must be performed by client code
*/
- public static function getFileKey(\OC_FilesystemView $view, $userId, $filePath) {
-
- $util = new Util($view, \OCP\User::getUser());
+ public static function getFileKey(\OC_FilesystemView $view, $util, $filePath) {
list($owner, $filename) = $util->getUidAndFilename($filePath);
$filename = Helper::stripPartialFileExtension($filename);
@@ -364,21 +362,19 @@ class Keymanager {
* @brief retrieve shareKey for an encrypted file
* @param \OC_FilesystemView $view
* @param string $userId
+ * @param \OCA\Encryption\Util $util
* @param string $filePath
* @internal param \OCA\Encryption\file $string name
* @return string file key or false
* @note The sharekey returned is encrypted. Decryption
* of the keyfile must be performed by client code
*/
- public static function getShareKey(\OC_FilesystemView $view, $userId, $filePath) {
+ public static function getShareKey(\OC_FilesystemView $view, $userId, $util, $filePath) {
// try reusing key file if part file
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
- //here we need the currently logged in user, while userId can be a different user
- $util = new Util($view, \OCP\User::getUser());
-
list($owner, $filename) = $util->getUidAndFilename($filePath);
$filename = Helper::stripPartialFileExtension($filename);
// in case of system wide mount points the keys are stored directly in the data directory
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index 54c3b9caa1..f7253b4591 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -260,7 +260,8 @@ class Proxy extends \OC_FileProxy {
$view = new \OC_FilesystemView('');
- $util = new Util($view, \OCP\USER::getUser());
+ $userId = Helper::getUser($path);
+ $util = new Util($view, $userId);
// If file is already encrypted, decrypt using crypto protocol
if (
@@ -323,7 +324,7 @@ class Proxy extends \OC_FileProxy {
$view = new \OC_FilesystemView('/');
- $userId = \OCP\User::getUser();
+ $userId = Helper::getUser($path);
$util = new Util($view, $userId);
// if encryption is no longer enabled or if the files aren't migrated yet
@@ -398,7 +399,7 @@ class Proxy extends \OC_FileProxy {
$view = new \OC_FilesystemView('/');
$session = new \OCA\Encryption\Session($view);
- $userId = \OCP\User::getUser();
+ $userId = Helper::getUser($path);
$util = new Util($view, $userId);
// split the path parts
diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php
index 1738955d1a..393c133d76 100644
--- a/apps/files_encryption/lib/stream.php
+++ b/apps/files_encryption/lib/stream.php
@@ -250,12 +250,14 @@ class Stream {
// Fetch and decrypt keyfile
// Fetch existing keyfile
- $this->encKeyfile = Keymanager::getFileKey($this->rootView, $this->userId, $this->relPath);
+ $userId = Helper::getUser($this->rawPath);
+ $util = new \OCA\Encryption\Util($this->rootView, $userId);
+ $this->encKeyfile = Keymanager::getFileKey($this->rootView, $util, $this->relPath);
// If a keyfile already exists
if ($this->encKeyfile) {
- $shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $this->relPath);
+ $shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $util, $this->relPath);
// if there is no valid private key return false
if ($this->privateKey === false) {
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index f9beb9de67..08c8870408 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -38,7 +38,8 @@ class Util {
const MIGRATION_OPEN = 0; // user still needs to be migrated
private $view; // OC_FilesystemView object for filesystem operations
- private $userId; // ID of the currently logged-in user
+ private $userId; // ID of the user we use to encrypt/decrypt files
+ private $ownerId; // ID of the user who accesses the file/folder
private $client; // Client side encryption mode flag
private $publicKeyDir; // Dir containing all public user keys
private $encryptionDir; // Dir containing user's files_encryption
@@ -58,51 +59,34 @@ class Util {
public function __construct(\OC_FilesystemView $view, $userId, $client = false) {
$this->view = $view;
- $this->userId = $userId;
$this->client = $client;
- $this->isPublic = false;
$this->publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId');
$this->recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
- // if we are anonymous/public
+ $this->userDir = '/' . $userId;
+ $this->fileFolderName = 'files';
+ $this->userFilesDir =
+ '/' . $userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
+ $this->publicKeyDir = '/' . 'public-keys';
+ $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
+ $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
+ $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
+ $this->publicKeyPath =
+ $this->publicKeyDir . '/' . $userId . '.public.key'; // e.g. data/public-keys/admin.public.key
+ $this->privateKeyPath =
+ $this->encryptionDir . '/' . $userId . '.private.key'; // e.g. data/admin/admin.private.key
+ // make sure that the owners home is mounted
+ \OC\Files\Filesystem::initMountPoints($userId);
+
if (\OCA\Encryption\Helper::isPublicAccess()) {
$this->userId = $this->publicShareKeyId;
-
- // only handle for files_sharing app
- if (isset($GLOBALS['app']) && $GLOBALS['app'] === 'files_sharing') {
- $this->userDir = '/' . $GLOBALS['fileOwner'];
- $this->fileFolderName = 'files';
- $this->userFilesDir = '/' . $GLOBALS['fileOwner'] . '/'
- . $this->fileFolderName; // TODO: Does this need to be user configurable?
- $this->publicKeyDir = '/' . 'public-keys';
- $this->encryptionDir = '/' . $GLOBALS['fileOwner'] . '/' . 'files_encryption';
- $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
- $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
- $this->publicKeyPath =
- $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
- $this->privateKeyPath =
- '/owncloud_private_key/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
- $this->isPublic = true;
- // make sure that the owners home is mounted
- \OC\Files\Filesystem::initMountPoints($GLOBALS['fileOwner']);
- }
-
+ $this->ownerId = $userId;
+ $this->isPublic = true;
} else {
- $this->userDir = '/' . $this->userId;
- $this->fileFolderName = 'files';
- $this->userFilesDir =
- '/' . $this->userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
- $this->publicKeyDir = '/' . 'public-keys';
- $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
- $this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
- $this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
- $this->publicKeyPath =
- $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
- $this->privateKeyPath =
- $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
- // make sure that the owners home is mounted
- \OC\Files\Filesystem::initMountPoints($this->userId);
+ $this->userId = $userId;
+ $this->ownerId = $userId;
+ $this->isPublic = false;
}
}
@@ -1338,7 +1322,7 @@ class Util {
// handle public access
if ($this->isPublic) {
$filename = $path;
- $fileOwnerUid = $GLOBALS['fileOwner'];
+ $fileOwnerUid = $this->ownerId;
return array(
$fileOwnerUid,
From e11afd306608798a8ba9138cae70e9ab283c490d Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Wed, 20 Nov 2013 22:44:23 +0100
Subject: [PATCH 05/47] fix some getShareKey() and getFileKey() calls
---
apps/files_encryption/lib/util.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 08c8870408..ce3d253cc9 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -351,7 +351,7 @@ class Util {
// scanning every file like this
// will eat server resources :(
if (
- Keymanager::getFileKey($this->view, $this->userId, $relPath)
+ Keymanager::getFileKey($this->view, $this, $relPath)
&& $isEncryptedPath
) {
@@ -1043,10 +1043,10 @@ class Util {
private function decryptKeyfile($filePath, $privateKey) {
// Get the encrypted keyfile
- $encKeyfile = Keymanager::getFileKey($this->view, $this->userId, $filePath);
+ $encKeyfile = Keymanager::getFileKey($this->view, $this, $filePath);
// The file has a shareKey and must use it for decryption
- $shareKey = Keymanager::getShareKey($this->view, $this->userId, $filePath);
+ $shareKey = Keymanager::getShareKey($this->view, $this->userId, $this, $filePath);
$plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
From b9c18d16fe67f71015d1a233e2716bc7c0812140 Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Wed, 20 Nov 2013 23:23:23 +0100
Subject: [PATCH 06/47] make sure that we always use the correct user id
---
apps/files_encryption/lib/keymanager.php | 18 +++++++++++-------
apps/files_encryption/lib/stream.php | 12 +++++++++---
apps/files_encryption/lib/util.php | 2 +-
3 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php
index 8d3e72b422..b207b1437b 100755
--- a/apps/files_encryption/lib/keymanager.php
+++ b/apps/files_encryption/lib/keymanager.php
@@ -125,8 +125,8 @@ class Keymanager {
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
- //here we need the currently logged in user, while userId can be a different user
- $util = new Util($view, \OCP\User::getUser());
+ $userId = Helper::getUser($path);
+ $util = new Util($view, $userId);
list($owner, $filename) = $util->getUidAndFilename($path);
// in case of system wide mount points the keys are stored directly in the data directory
@@ -225,7 +225,8 @@ class Keymanager {
$trimmed = ltrim($path, '/');
- $util = new Util($view, \OCP\User::getUser());
+ $userId = Helper::getUser($path);
+ $util = new Util($view, $userId);
if($util->isSystemWideMountPoint($path)) {
$keyPath = '/files_encryption/keyfiles/' . $trimmed;
@@ -322,8 +323,10 @@ class Keymanager {
// $shareKeys must be an array with the following format:
// [userId] => [encrypted key]
- // Here we need the currently logged in user, while userId can be a different user
- $util = new Util($view, \OCP\User::getUser());
+
+ $userId = Helper::getUser($path);
+
+ $util = new Util($view, $userId);
list($owner, $filename) = $util->getUidAndFilename($path);
@@ -441,8 +444,9 @@ class Keymanager {
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
- //here we need the currently logged in user, while userId can be a different user
- $util = new Util($view, \OCP\User::getUser());
+ $userId = Helper::getUser($filePath);
+
+ $util = new Util($view, $userId);
list($owner, $filename) = $util->getUidAndFilename($filePath);
diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php
index 393c133d76..2497e56e89 100644
--- a/apps/files_encryption/lib/stream.php
+++ b/apps/files_encryption/lib/stream.php
@@ -92,10 +92,14 @@ class Stream {
$this->session = new \OCA\Encryption\Session($this->rootView);
- $this->privateKey = $this->session->getPrivateKey($this->userId);
+ $this->privateKey = $this->session->getPrivateKey();
- $util = new Util($this->rootView, \OCP\USER::getUser());
+ $userId = Helper::getUser($path);
+ $util = new Util($this->rootView, $userId);
+
+ // need to get the userId once more from util, because now this can be the
+ // public share key ID
$this->userId = $util->getUserId();
// rawPath is relative to the data directory
@@ -509,7 +513,9 @@ class Stream {
// Check if OC sharing api is enabled
$sharingEnabled = \OCP\Share::isEnabled();
- $util = new Util($this->rootView, $this->userId);
+ $userId = Helper::getUser($this->rawPath);
+
+ $util = new Util($this->rootView, $userId);
// Get all users sharing the file includes current user
$uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath, $this->userId);
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index ce3d253cc9..1e8b852fb3 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -69,7 +69,7 @@ class Util {
$this->userFilesDir =
'/' . $userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
$this->publicKeyDir = '/' . 'public-keys';
- $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
+ $this->encryptionDir = '/' . $userId . '/' . 'files_encryption';
$this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
$this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
$this->publicKeyPath =
From 318db64b2d9f724c3209bd6ca97f560840e2cc20 Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Wed, 20 Nov 2013 23:27:42 +0100
Subject: [PATCH 07/47] adapt tests to the new code
---
apps/files_encryption/tests/crypt.php | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/apps/files_encryption/tests/crypt.php b/apps/files_encryption/tests/crypt.php
index 5146613e25..0086371d22 100755
--- a/apps/files_encryption/tests/crypt.php
+++ b/apps/files_encryption/tests/crypt.php
@@ -157,6 +157,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$filename = 'tmp-' . time() . '.test';
+ $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId);
+
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/'. $filename, $this->dataShort);
// Test that data was successfully written
@@ -176,10 +178,10 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$this->assertNotEquals($this->dataShort, $retreivedCryptedFile);
// Get the encrypted keyfile
- $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename);
+ $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $util, $filename);
// Attempt to fetch the user's shareKey
- $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename);
+ $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $util, $filename);
// get session
$session = new \OCA\Encryption\Session($this->view);
@@ -214,6 +216,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
// Generate a a random filename
$filename = 'tmp-' . time() . '.test';
+ $util = new Encryption\Util(new \OC_FilesystemView(), $this->userId);
+
// Save long data as encrypted file using stream wrapper
$cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong);
@@ -244,16 +248,16 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
$i = 0;
while ($i < count($r)-1) {
$e[] = $r[$i] . $r[$i+1];
- $i = $i + 2;
+ $i = $i + 2;
}
//print_r($e);
// Get the encrypted keyfile
- $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $this->userId, $filename);
+ $encKeyfile = Encryption\Keymanager::getFileKey($this->view, $util, $filename);
// Attempt to fetch the user's shareKey
- $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $filename);
+ $shareKey = Encryption\Keymanager::getShareKey($this->view, $this->userId, $util, $filename);
// get session
$session = new \OCA\Encryption\Session($this->view);
@@ -387,7 +391,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @brief test decryption using legacy blowfish method
*/
function testLegacyDecryptShort() {
-
+
$crypted = $this->legacyEncrypt($this->dataShort, $this->pass);
$decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass);
@@ -401,7 +405,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
* @brief test decryption using legacy blowfish method
*/
function testLegacyDecryptLong() {
-
+
$crypted = $this->legacyEncrypt($this->dataLong, $this->pass);
$decrypted = Encryption\Crypt::legacyBlockDecrypt($crypted, $this->pass);
@@ -653,8 +657,8 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
// tear down
$view->unlink($filename);
}
-
-
+
+
/**
* @brief encryption using legacy blowfish method
* @param $data string data to encrypt
From b27fc42e1f0fbd1edebb1eb1818de4b4e0c4ee4b Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Thu, 21 Nov 2013 00:23:38 +0100
Subject: [PATCH 08/47] public upload now also works with encryption enabled
---
apps/files/index.php | 1 -
apps/files_encryption/lib/keymanager.php | 14 +++++---------
apps/files_encryption/lib/proxy.php | 7 +++----
apps/files_encryption/lib/stream.php | 14 +++++++-------
apps/files_encryption/lib/util.php | 4 ++--
apps/files_encryption/tests/keymanager.php | 4 +++-
apps/files_sharing/public.php | 3 ---
7 files changed, 20 insertions(+), 27 deletions(-)
diff --git a/apps/files/index.php b/apps/files/index.php
index 9ae378d7a1..8f6838aa0d 100644
--- a/apps/files/index.php
+++ b/apps/files/index.php
@@ -108,7 +108,6 @@ if ($needUpgrade) {
// if the encryption app is disabled, than everything is fine (INIT_SUCCESSFUL status code)
$encryptionInitStatus = 2;
if (OC_App::isEnabled('files_encryption')) {
- $publicUploadEnabled = 'no';
$session = new \OCA\Encryption\Session(new \OC\Files\View('/'));
$encryptionInitStatus = $session->getInitialized();
}
diff --git a/apps/files_encryption/lib/keymanager.php b/apps/files_encryption/lib/keymanager.php
index b207b1437b..b4396864a4 100755
--- a/apps/files_encryption/lib/keymanager.php
+++ b/apps/files_encryption/lib/keymanager.php
@@ -112,6 +112,7 @@ class Keymanager {
* @brief store file encryption key
*
* @param \OC_FilesystemView $view
+ * @param \OCA\Encryption\Util $util
* @param string $path relative path of the file, including filename
* @param $userId
* @param $catfile
@@ -120,13 +121,11 @@ class Keymanager {
* @note The keyfile is not encrypted here. Client code must
* asymmetrically encrypt the keyfile before passing it to this method
*/
- public static function setFileKey(\OC_FilesystemView $view, $path, $userId, $catfile) {
+ public static function setFileKey(\OC_FilesystemView $view, $util, $path, $userId, $catfile) {
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
- $userId = Helper::getUser($path);
- $util = new Util($view, $userId);
list($owner, $filename) = $util->getUidAndFilename($path);
// in case of system wide mount points the keys are stored directly in the data directory
@@ -315,19 +314,16 @@ class Keymanager {
/**
* @brief store multiple share keys for a single file
* @param \OC_FilesystemView $view
- * @param $path
+ * @param \OCA\Encryption\Util $util
+ * @param string $path
* @param array $shareKeys
* @return bool
*/
- public static function setShareKeys(\OC_FilesystemView $view, $path, array $shareKeys) {
+ public static function setShareKeys(\OC_FilesystemView $view, $util, $path, array $shareKeys) {
// $shareKeys must be an array with the following format:
// [userId] => [encrypted key]
- $userId = Helper::getUser($path);
-
- $util = new Util($view, $userId);
-
list($owner, $filename) = $util->getUidAndFilename($path);
// in case of system wide mount points the keys are stored directly in the data directory
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index f7253b4591..43d451d67c 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -47,8 +47,10 @@ class Proxy extends \OC_FileProxy {
*/
private static function shouldEncrypt($path) {
+ $userId = Helper::getUser($path);
+
if (\OCP\App::isEnabled('files_encryption') === false || Crypt::mode() !== 'server' ||
- strpos($path, '/' . \OCP\User::getUser() . '/files') !== 0) {
+ strpos($path, '/' . $userId . '/files') !== 0) {
return false;
}
@@ -244,9 +246,6 @@ class Proxy extends \OC_FileProxy {
// split the path parts
$pathParts = explode('/', $path);
- // get relative path
- $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
-
// FIXME: handling for /userId/cache used by webdav for chunking. The cache chunks are NOT encrypted
if (isset($pathParts[2]) && $pathParts[2] === 'cache') {
return $result;
diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php
index 2497e56e89..3fbcf7db3e 100644
--- a/apps/files_encryption/lib/stream.php
+++ b/apps/files_encryption/lib/stream.php
@@ -90,11 +90,14 @@ class Stream {
$this->rootView = new \OC_FilesystemView('/');
}
+ // rawPath is relative to the data directory
+ $this->rawPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
+
$this->session = new \OCA\Encryption\Session($this->rootView);
$this->privateKey = $this->session->getPrivateKey();
- $userId = Helper::getUser($path);
+ $userId = Helper::getUser($this->rawPath);
$util = new Util($this->rootView, $userId);
@@ -102,9 +105,6 @@ class Stream {
// public share key ID
$this->userId = $util->getUserId();
- // rawPath is relative to the data directory
- $this->rawPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
-
// Strip identifier text from path, this gives us the path relative to data//files
$this->relPath = Helper::stripUserFilesPath($this->rawPath);
// if raw path doesn't point to a real file, check if it is a version or a file in the trash bin
@@ -518,7 +518,7 @@ class Stream {
$util = new Util($this->rootView, $userId);
// Get all users sharing the file includes current user
- $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath, $this->userId);
+ $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath, $userId);
$checkedUserIds = $util->filterShareReadyUsers($uniqueUserIds);
// Fetch public keys for all sharing users
@@ -528,10 +528,10 @@ class Stream {
$this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys);
// Save the new encrypted file key
- Keymanager::setFileKey($this->rootView, $this->relPath, $this->userId, $this->encKeyfiles['data']);
+ Keymanager::setFileKey($this->rootView, $util, $this->relPath, $userId, $this->encKeyfiles['data']);
// Save the sharekeys
- Keymanager::setShareKeys($this->rootView, $this->relPath, $this->encKeyfiles['keys']);
+ Keymanager::setShareKeys($this->rootView, $util, $this->relPath, $this->encKeyfiles['keys']);
// Re-enable proxy - our work is done
\OC_FileProxy::$enabled = $proxyStatus;
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 1e8b852fb3..b15c61f599 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -1097,8 +1097,8 @@ class Util {
// Save the recrypted key to it's owner's keyfiles directory
// Save new sharekeys to all necessary user directory
if (
- !Keymanager::setFileKey($this->view, $filePath, $fileOwner, $multiEncKey['data'])
- || !Keymanager::setShareKeys($this->view, $filePath, $multiEncKey['keys'])
+ !Keymanager::setFileKey($this->view, $this, $filePath, $fileOwner, $multiEncKey['data'])
+ || !Keymanager::setShareKeys($this->view, $this, $filePath, $multiEncKey['keys'])
) {
\OCP\Util::writeLog('Encryption library',
diff --git a/apps/files_encryption/tests/keymanager.php b/apps/files_encryption/tests/keymanager.php
index ad6bbd3a7e..72ee270ee5 100644
--- a/apps/files_encryption/tests/keymanager.php
+++ b/apps/files_encryption/tests/keymanager.php
@@ -145,13 +145,15 @@ class Test_Encryption_Keymanager extends \PHPUnit_Framework_TestCase {
$file = 'unittest-' . time() . '.txt';
+ $util = new Encryption\Util($this->view, $this->userId);
+
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$this->view->file_put_contents($this->userId . '/files/' . $file, $this->dataShort);
- Encryption\Keymanager::setFileKey($this->view, $file, $this->userId, $key);
+ Encryption\Keymanager::setFileKey($this->view, $util, $file, $this->userId, $key);
$this->assertTrue($this->view->file_exists('/' . $this->userId . '/files_encryption/keyfiles/' . $file . '.key'));
diff --git a/apps/files_sharing/public.php b/apps/files_sharing/public.php
index d59f9b7401..f809196701 100644
--- a/apps/files_sharing/public.php
+++ b/apps/files_sharing/public.php
@@ -152,9 +152,6 @@ if (isset($path)) {
$tmpl->assign('sharingToken', $token);
$tmpl->assign('disableSharing', true);
$allowPublicUploadEnabled = (bool) ($linkItem['permissions'] & OCP\PERMISSION_CREATE);
- if (\OCP\App::isEnabled('files_encryption')) {
- $allowPublicUploadEnabled = false;
- }
if (OC_Appconfig::getValue('core', 'shareapi_allow_public_upload', 'yes') === 'no') {
$allowPublicUploadEnabled = false;
}
From 2b361ea085812a7b97102d026c421905549b5142 Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Thu, 21 Nov 2013 10:09:07 +0100
Subject: [PATCH 09/47] better distinction between userID and keyId
---
apps/files_encryption/lib/stream.php | 30 ++++++++++++--------------
apps/files_encryption/lib/util.php | 32 +++++++++++++++++-----------
2 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php
index 2497e56e89..409c6ff627 100644
--- a/apps/files_encryption/lib/stream.php
+++ b/apps/files_encryption/lib/stream.php
@@ -55,6 +55,7 @@ class Stream {
private $rawPath; // The raw path relative to the data dir
private $relPath; // rel path to users file dir
private $userId;
+ private $keyId;
private $handle; // Resource returned by fopen
private $meta = array(); // Header / meta for source stream
private $writeCache;
@@ -94,17 +95,17 @@ class Stream {
$this->privateKey = $this->session->getPrivateKey();
- $userId = Helper::getUser($path);
-
- $util = new Util($this->rootView, $userId);
-
- // need to get the userId once more from util, because now this can be the
- // public share key ID
- $this->userId = $util->getUserId();
-
// rawPath is relative to the data directory
$this->rawPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
+ $this->userId = Helper::getUser($this->rawPath);
+
+ $util = new Util($this->rootView, $this->userId);
+
+ // get the key ID which we want to use, canm be the users key or the
+ // public share key
+ $this->keyId = $util->getKeyId();
+
// Strip identifier text from path, this gives us the path relative to data//files
$this->relPath = Helper::stripUserFilesPath($this->rawPath);
// if raw path doesn't point to a real file, check if it is a version or a file in the trash bin
@@ -254,14 +255,13 @@ class Stream {
// Fetch and decrypt keyfile
// Fetch existing keyfile
- $userId = Helper::getUser($this->rawPath);
- $util = new \OCA\Encryption\Util($this->rootView, $userId);
+ $util = new \OCA\Encryption\Util($this->rootView, $this->userId);
$this->encKeyfile = Keymanager::getFileKey($this->rootView, $util, $this->relPath);
// If a keyfile already exists
if ($this->encKeyfile) {
- $shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $util, $this->relPath);
+ $shareKey = Keymanager::getShareKey($this->rootView, $this->keyId, $util, $this->relPath);
// if there is no valid private key return false
if ($this->privateKey === false) {
@@ -508,14 +508,12 @@ class Stream {
\OC_FileProxy::$enabled = false;
// Fetch user's public key
- $this->publicKey = Keymanager::getPublicKey($this->rootView, $this->userId);
+ $this->publicKey = Keymanager::getPublicKey($this->rootView, $this->keyId);
// Check if OC sharing api is enabled
$sharingEnabled = \OCP\Share::isEnabled();
- $userId = Helper::getUser($this->rawPath);
-
- $util = new Util($this->rootView, $userId);
+ $util = new Util($this->rootView, $this->userId);
// Get all users sharing the file includes current user
$uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath, $this->userId);
@@ -528,7 +526,7 @@ class Stream {
$this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys);
// Save the new encrypted file key
- Keymanager::setFileKey($this->rootView, $this->relPath, $this->userId, $this->encKeyfiles['data']);
+ Keymanager::setFileKey($this->rootView, $this->relPath, $this->keyId, $this->encKeyfiles['data']);
// Save the sharekeys
Keymanager::setShareKeys($this->rootView, $this->relPath, $this->encKeyfiles['keys']);
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 1e8b852fb3..2dd4fd9c16 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -39,7 +39,7 @@ class Util {
private $view; // OC_FilesystemView object for filesystem operations
private $userId; // ID of the user we use to encrypt/decrypt files
- private $ownerId; // ID of the user who accesses the file/folder
+ private $keyId; // ID of the key we want to manipulate
private $client; // Client side encryption mode flag
private $publicKeyDir; // Dir containing all public user keys
private $encryptionDir; // Dir containing user's files_encryption
@@ -60,32 +60,31 @@ class Util {
$this->view = $view;
$this->client = $client;
+ $this->userId = $userId;
$this->publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId');
$this->recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
- $this->userDir = '/' . $userId;
+ $this->userDir = '/' . $this->userId;
$this->fileFolderName = 'files';
$this->userFilesDir =
'/' . $userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
$this->publicKeyDir = '/' . 'public-keys';
- $this->encryptionDir = '/' . $userId . '/' . 'files_encryption';
+ $this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
$this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
$this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
$this->publicKeyPath =
- $this->publicKeyDir . '/' . $userId . '.public.key'; // e.g. data/public-keys/admin.public.key
+ $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
$this->privateKeyPath =
- $this->encryptionDir . '/' . $userId . '.private.key'; // e.g. data/admin/admin.private.key
+ $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
// make sure that the owners home is mounted
\OC\Files\Filesystem::initMountPoints($userId);
if (\OCA\Encryption\Helper::isPublicAccess()) {
- $this->userId = $this->publicShareKeyId;
- $this->ownerId = $userId;
+ $this->keyId = $this->publicShareKeyId;
$this->isPublic = true;
} else {
- $this->userId = $userId;
- $this->ownerId = $userId;
+ $this->keyId = $this->userId;
$this->isPublic = false;
}
}
@@ -172,13 +171,13 @@ class Util {
// check if public-key exists but private-key is missing
if ($this->view->file_exists($this->publicKeyPath) && !$this->view->file_exists($this->privateKeyPath)) {
\OCP\Util::writeLog('Encryption library',
- 'public key exists but private key is missing for "' . $this->userId . '"', \OCP\Util::FATAL);
+ 'public key exists but private key is missing for "' . $this->keyId . '"', \OCP\Util::FATAL);
return false;
} else {
if (!$this->view->file_exists($this->publicKeyPath) && $this->view->file_exists($this->privateKeyPath)
) {
\OCP\Util::writeLog('Encryption library',
- 'private key exists but public key is missing for "' . $this->userId . '"', \OCP\Util::FATAL);
+ 'private key exists but public key is missing for "' . $this->keyId . '"', \OCP\Util::FATAL);
return false;
}
}
@@ -1046,7 +1045,7 @@ class Util {
$encKeyfile = Keymanager::getFileKey($this->view, $this, $filePath);
// The file has a shareKey and must use it for decryption
- $shareKey = Keymanager::getShareKey($this->view, $this->userId, $this, $filePath);
+ $shareKey = Keymanager::getShareKey($this->view, $this->keyId, $this, $filePath);
$plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
@@ -1322,7 +1321,7 @@ class Util {
// handle public access
if ($this->isPublic) {
$filename = $path;
- $fileOwnerUid = $this->ownerId;
+ $fileOwnerUid = $this->userId;
return array(
$fileOwnerUid,
@@ -1547,6 +1546,13 @@ class Util {
return $this->userId;
}
+ /**
+ * @return string
+ */
+ public function getKeyId() {
+ return $this->keyId;
+ }
+
/**
* @return string
*/
From c7dc6dc2c2d0d2de72256a6f7bcacaf3ec59bd0c Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Thu, 21 Nov 2013 11:11:15 +0100
Subject: [PATCH 10/47] fix getFileKey() call
---
apps/files_encryption/lib/util.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index a9468e34d4..ca9651742f 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -461,7 +461,7 @@ class Util {
$relPath = Helper::stripUserFilesPath($path);
}
- $fileKey = Keymanager::getFileKey($this->view, $relPath);
+ $fileKey = Keymanager::getFileKey($this->view, $this, $relPath);
if ($fileKey === false) {
return false;
From d2e6f7d9790d42faf9d79b7beb07b2d287fd2da3 Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Thu, 21 Nov 2013 15:57:49 +0100
Subject: [PATCH 11/47] check HTTP Referer to check if we come from public.php
or from a internal page. Necessary to detect public access also if a user is
logged in.
---
apps/files_encryption/lib/helper.php | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index e66a84d909..897b5d4662 100755
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -225,7 +225,7 @@ class Helper {
* @return bool
*/
public static function isPublicAccess() {
- if (\OCP\USER::getUser() === false) {
+ if (strpos($_SERVER['HTTP_REFERER'], 'public.php') !== false) {
return true;
} else {
return false;
@@ -252,16 +252,22 @@ class Helper {
return $relPath;
}
+ /**
+ * @brief get user from the path, because we can't assume that \OCP\User::getUser()
+ * will always return the right result
+ * @param type $path
+ * @return boolean
+ */
public static function getUser($path) {
$user = \OCP\User::getUser();
- // if we are logged in, than we return the userid
- if ($user) {
+ // if we are logged in and if we don't come from a public URL, then we return the userid
+ if ($user && strpos($_SERVER['HTTP_REFERER'], 'public.php') === false) {
return $user;
}
- // if no user is logged in we try to access a publically shared files.
+ // ...otherwise we try to access a publically shared files.
// In this case we need to try to get the user from the path
$trimmed = ltrim($path, '/');
From 54f0deff2ae60b2914f2cd1f20e7bcb23726edac Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Thu, 21 Nov 2013 17:02:37 +0100
Subject: [PATCH 12/47] LDAP: get user photo from LDAP and set it as avatar if
available
---
apps/user_ldap/lib/configuration.php | 3 ++
apps/user_ldap/user_ldap.php | 63 +++++++++++++++++++++++++++-
2 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php
index e14ed824a7..58f4b11e69 100644
--- a/apps/user_ldap/lib/configuration.php
+++ b/apps/user_ldap/lib/configuration.php
@@ -72,6 +72,7 @@ class Configuration {
'ldapExpertUsernameAttr' => null,
'ldapExpertUUIDUserAttr' => null,
'ldapExpertUUIDGroupAttr' => null,
+ 'lastJpegPhotoLookup' => null,
);
public function __construct($configPrefix, $autoread = true) {
@@ -330,6 +331,7 @@ class Configuration {
'ldap_expert_uuid_user_attr' => '',
'ldap_expert_uuid_group_attr' => '',
'has_memberof_filter_support' => 0,
+ 'last_jpegPhoto_lookup' => 0,
);
}
@@ -377,6 +379,7 @@ class Configuration {
'ldap_expert_uuid_user_attr' => 'ldapExpertUUIDUserAttr',
'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr',
'has_memberof_filter_support' => 'hasMemberOfFilterSupport',
+ 'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
);
return $array;
}
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index 6f52bbdf23..2bff4b2821 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -69,6 +69,65 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
}
}
+ /**
+ * @brief reads jpegPhoto and set is as avatar if available
+ * @param $uid string ownCloud user name
+ * @param $dn string the user's LDAP DN
+ * @return void
+ */
+ private function updateAvatar($uid, $dn) {
+ $lastChecked = $this->access->connection->lastJpegPhotoLookup;
+ if((time() - $lastChecked) < 86400 ) {
+ //update only once a day
+ return;
+ }
+
+ $jpegPhoto = $this->access->readAttribute($dn, 'jpegPhoto');
+ $this->access->connection->lastJpegPhotoLookup = time();
+ if(!$jpegPhoto || !is_array($jpegPhoto) || !isset($jpegPhoto[0])) {
+ //not set, nothing left to do;
+ return;
+ }
+
+ $image = new \OCP\Image($jpegPhoto[0]);
+ if(!$image->valid()) {
+ \OCP\Util::writeLog('user_ldap', 'jpegPhoto data invalid for '.$dn,
+ \OCP\Util::ERROR);
+ return;
+ }
+ //make sure it is a square and not bigger than 128x128
+ $size = min(array($image->width(), $image->height(), 128));
+ if(!$image->centerCrop($size)) {
+ \OCP\Util::writeLog('user_ldap',
+ 'croping image for avatar failed for '.$dn,
+ \OCP\Util::ERROR);
+ return;
+ }
+
+ $avatarManager = \OC::$server->getAvatarManager();
+ $avatar = $avatarManager->getAvatar($uid);
+ $avatar->set($image->data());
+ }
+
+ /**
+ * @brief checks whether the user is allowed to change his avatar in ownCloud
+ * @param $uid string the ownCloud user name
+ * @return boolean either the user can or cannot
+ */
+ public function canChangeAvatar($uid) {
+ $dn = $this->access->username2dn($uid);
+ if(!$dn) {
+ return false;
+ }
+ $jpegPhoto = $this->access->readAttribute($dn, 'jpegPhoto');
+ if(!$jpegPhoto || !is_array($jpegPhoto) || !isset($jpegPhoto[0])) {
+ //The user is allowed to change his avatar in ownCloud only if no
+ //avatar is provided by LDAP
+ return true;
+ }
+ return false;
+ }
+
/**
* @brief Check if the password is correct
* @param $uid The username
@@ -173,6 +232,7 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
$this->access->connection->writeToCache('userExists'.$uid, true);
$this->updateQuota($dn);
+ $this->updateAvatar($uid, $dn);
return true;
}
@@ -289,7 +349,8 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
public function implementsActions($actions) {
return (bool)((OC_USER_BACKEND_CHECK_PASSWORD
| OC_USER_BACKEND_GET_HOME
- | OC_USER_BACKEND_GET_DISPLAYNAME)
+ | OC_USER_BACKEND_GET_DISPLAYNAME
+ | OC_USER_BACKEND_PROVIDE_AVATAR)
& $actions);
}
From 8ccac86c9893fe0af1715288ce29d85091bca9aa Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Fri, 22 Nov 2013 13:24:11 +0100
Subject: [PATCH 13/47] Enable user backends to provide avatar images
---
lib/private/user.php | 16 +++++++
lib/private/user/backend.php | 15 ++++---
lib/private/user/user.php | 12 ++++++
settings/personal.php | 1 +
settings/templates/personal.php | 4 ++
tests/lib/user/avataruserdummy.php | 27 ++++++++++++
tests/lib/user/user.php | 69 ++++++++++++++++++++++++++++++
7 files changed, 137 insertions(+), 7 deletions(-)
create mode 100644 tests/lib/user/avataruserdummy.php
diff --git a/lib/private/user.php b/lib/private/user.php
index f15fdf1dbb..d4be8eb9bd 100644
--- a/lib/private/user.php
+++ b/lib/private/user.php
@@ -412,6 +412,22 @@ class OC_User {
}
}
+ /**
+ * @brief Check whether user can change his avatar
+ * @param string $uid The username
+ * @return bool
+ *
+ * Check whether a specified user can change his avatar
+ */
+ public static function canUserChangeAvatar($uid) {
+ $user = self::getManager()->get($uid);
+ if ($user) {
+ return $user->canChangeAvatar();
+ } else {
+ return false;
+ }
+ }
+
/**
* @brief Check whether user can change his password
* @param string $uid The username
diff --git a/lib/private/user/backend.php b/lib/private/user/backend.php
index e9be08e429..02c93d13bd 100644
--- a/lib/private/user/backend.php
+++ b/lib/private/user/backend.php
@@ -31,13 +31,13 @@ define('OC_USER_BACKEND_NOT_IMPLEMENTED', -501);
/**
* actions that user backends can define
*/
-define('OC_USER_BACKEND_CREATE_USER', 0x000001);
-define('OC_USER_BACKEND_SET_PASSWORD', 0x000010);
-define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100);
-define('OC_USER_BACKEND_GET_HOME', 0x001000);
-define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x010000);
-define('OC_USER_BACKEND_SET_DISPLAYNAME', 0x100000);
-
+define('OC_USER_BACKEND_CREATE_USER', 0x0000001);
+define('OC_USER_BACKEND_SET_PASSWORD', 0x0000010);
+define('OC_USER_BACKEND_CHECK_PASSWORD', 0x0000100);
+define('OC_USER_BACKEND_GET_HOME', 0x0001000);
+define('OC_USER_BACKEND_GET_DISPLAYNAME', 0x0010000);
+define('OC_USER_BACKEND_SET_DISPLAYNAME', 0x0100000);
+define('OC_USER_BACKEND_PROVIDE_AVATAR', 0x1000000);
/**
* Abstract base class for user management. Provides methods for querying backend
@@ -54,6 +54,7 @@ abstract class OC_User_Backend implements OC_User_Interface {
OC_USER_BACKEND_GET_HOME => 'getHome',
OC_USER_BACKEND_GET_DISPLAYNAME => 'getDisplayName',
OC_USER_BACKEND_SET_DISPLAYNAME => 'setDisplayName',
+ OC_USER_BACKEND_PROVIDE_AVATAR => 'canChangeAvatar',
);
/**
diff --git a/lib/private/user/user.php b/lib/private/user/user.php
index e5f842944f..e773473ec4 100644
--- a/lib/private/user/user.php
+++ b/lib/private/user/user.php
@@ -139,6 +139,18 @@ class User {
return \OC_Config::getValue("datadirectory", \OC::$SERVERROOT . "/data") . '/' . $this->uid; //TODO switch to Config object once implemented
}
+ /**
+ * check if the backend allows the user to change his avatar on Personal page
+ *
+ * @return bool
+ */
+ public function canChangeAvatar() {
+ if($this->backend->implementsActions(\OC_USER_BACKEND_PROVIDE_AVATAR)) {
+ return $this->backend->canChangeAvatar($this->uid);
+ }
+ return true;
+ }
+
/**
* check if the backend supports changing passwords
*
diff --git a/settings/personal.php b/settings/personal.php
index 670e18e20e..44e1048941 100644
--- a/settings/personal.php
+++ b/settings/personal.php
@@ -90,6 +90,7 @@ $tmpl->assign('displayNameChangeSupported', OC_User::canUserChangeDisplayName(OC
$tmpl->assign('displayName', OC_User::getDisplayName());
$tmpl->assign('enableDecryptAll' , $enableDecryptAll);
$tmpl->assign('enableAvatars', \OC_Config::getValue('enable_avatars', true));
+$tmpl->assign('avatarChangeSupported', OC_User::canUserChangeAvatar(OC_User::getUser()));
$forms=OC_App::getForms('personal');
$tmpl->assign('forms', array());
diff --git a/settings/templates/personal.php b/settings/templates/personal.php
index 9d21e18e73..27a581af9c 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.php
@@ -87,11 +87,15 @@ if($_['passwordChangeSupported']) {
+
t('Upload new')); ?>
t('Select new from Files')); ?>
t('Remove image')); ?>
t('Either png or jpg. Ideally square but you will be able to crop it.')); ?>
+
+ t('Your avatar is provided by your original account.')); ?>
+
t('Abort')); ?>
diff --git a/tests/lib/user/avataruserdummy.php b/tests/lib/user/avataruserdummy.php
new file mode 100644
index 0000000000..738b10492e
--- /dev/null
+++ b/tests/lib/user/avataruserdummy.php
@@ -0,0 +1,27 @@
+.
+*
+*/
+
+class Avatar_User_Dummy extends \OC_User_Dummy {
+ public function canChangeAvatar($uid) {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/tests/lib/user/user.php b/tests/lib/user/user.php
index de5ccbf38c..0bbcda013c 100644
--- a/tests/lib/user/user.php
+++ b/tests/lib/user/user.php
@@ -87,6 +87,75 @@ class User extends \PHPUnit_Framework_TestCase {
$this->assertFalse($user->setPassword('bar',''));
}
+ public function testChangeAvatarSupportedYes() {
+ /**
+ * @var \OC_User_Backend | \PHPUnit_Framework_MockObject_MockObject $backend
+ */
+ require_once 'avataruserdummy.php';
+ $backend = $this->getMock('Avatar_User_Dummy');
+ $backend->expects($this->once())
+ ->method('canChangeAvatar')
+ ->with($this->equalTo('foo'))
+ ->will($this->returnValue(true));
+
+ $backend->expects($this->any())
+ ->method('implementsActions')
+ ->will($this->returnCallback(function ($actions) {
+ if ($actions === \OC_USER_BACKEND_PROVIDE_AVATAR) {
+ return true;
+ } else {
+ return false;
+ }
+ }));
+
+ $user = new \OC\User\User('foo', $backend);
+ $this->assertTrue($user->canChangeAvatar());
+ }
+
+ public function testChangeAvatarSupportedNo() {
+ /**
+ * @var \OC_User_Backend | \PHPUnit_Framework_MockObject_MockObject $backend
+ */
+ require_once 'avataruserdummy.php';
+ $backend = $this->getMock('Avatar_User_Dummy');
+ $backend->expects($this->once())
+ ->method('canChangeAvatar')
+ ->with($this->equalTo('foo'))
+ ->will($this->returnValue(false));
+
+ $backend->expects($this->any())
+ ->method('implementsActions')
+ ->will($this->returnCallback(function ($actions) {
+ if ($actions === \OC_USER_BACKEND_PROVIDE_AVATAR) {
+ return true;
+ } else {
+ return false;
+ }
+ }));
+
+ $user = new \OC\User\User('foo', $backend);
+ $this->assertFalse($user->canChangeAvatar());
+ }
+
+ public function testChangeAvatarNotSupported() {
+ /**
+ * @var \OC_User_Backend | \PHPUnit_Framework_MockObject_MockObject $backend
+ */
+ require_once 'avataruserdummy.php';
+ $backend = $this->getMock('Avatar_User_Dummy');
+ $backend->expects($this->never())
+ ->method('canChangeAvatar');
+
+ $backend->expects($this->any())
+ ->method('implementsActions')
+ ->will($this->returnCallback(function ($actions) {
+ return false;
+ }));
+
+ $user = new \OC\User\User('foo', $backend);
+ $this->assertTrue($user->canChangeAvatar());
+ }
+
public function testDelete() {
/**
* @var \OC_User_Backend | \PHPUnit_Framework_MockObject_MockObject $backend
From 6fdce3b7e92a5c93134719cd2d4934a73f943e02 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Fri, 22 Nov 2013 13:24:38 +0100
Subject: [PATCH 14/47] LDAP: user proxy must support canChangeAvatar too
---
apps/user_ldap/user_proxy.php | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/apps/user_ldap/user_proxy.php b/apps/user_ldap/user_proxy.php
index 092fdbf7c7..3c2821e87b 100644
--- a/apps/user_ldap/user_proxy.php
+++ b/apps/user_ldap/user_proxy.php
@@ -163,6 +163,15 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
return $this->handleRequest($uid, 'getDisplayName', array($uid));
}
+ /**
+ * @brief checks whether the user is allowed to change his avatar in ownCloud
+ * @param $uid string the ownCloud user name
+ * @return boolean either the user can or cannot
+ */
+ public function canChangeAvatar($uid) {
+ return $this->handleRequest($uid, 'canChangeAvatar', array($uid));
+ }
+
/**
* @brief Get a list of all display names
* @returns array with all displayNames (value) and the corresponding uids (key)
From 6085878966e44ff53d1d088ae6776ebfba70ff72 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Fri, 22 Nov 2013 23:57:23 +0100
Subject: [PATCH 15/47] Avatar: accept OC_Image as in setParameter
---
lib/private/avatar.php | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/private/avatar.php b/lib/private/avatar.php
index 814a9b22be..e97f55eeca 100644
--- a/lib/private/avatar.php
+++ b/lib/private/avatar.php
@@ -44,15 +44,19 @@ class OC_Avatar implements \OCP\IAvatar {
/**
* @brief sets the users avatar
- * @param $data mixed imagedata or path to set a new avatar
+ * @param $data mixed OC_Image, imagedata or path to set a new avatar
* @throws Exception if the provided file is not a jpg or png image
* @throws Exception if the provided image is not valid
* @throws \OC\NotSquareException if the image is not square
* @return void
*/
public function set ($data) {
-
- $img = new OC_Image($data);
+ if($data instanceOf OC_Image) {
+ $img = $data;
+ $data = $img->data();
+ } else {
+ $img = new OC_Image($data);
+ }
$type = substr($img->mimeType(), -3);
if ($type === 'peg') {
$type = 'jpg';
From d9347f2c9b1411a06a742e45702d6c27d7a2d1b4 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Fri, 22 Nov 2013 23:58:30 +0100
Subject: [PATCH 16/47] LDAP: last avatar lookup must be stored per user.
Someone had a blackout, eh?
---
apps/user_ldap/user_ldap.php | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index 2bff4b2821..97fc2fbb6c 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -76,20 +76,22 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
* @return void
*/
private function updateAvatar($uid, $dn) {
- $lastChecked = $this->access->connection->lastJpegPhotoLookup;
+ $lastChecked = \OCP\Config::getUserValue($uid, 'user_ldap', 'lastJpegPhotoLookup', 0);
if((time() - $lastChecked) < 86400 ) {
//update only once a day
return;
}
$jpegPhoto = $this->access->readAttribute($dn, 'jpegPhoto');
- $this->access->connection->lastJpegPhotoLookup = time();
+ \OCP\Config::setUserValue($uid, 'user_ldap', 'lastJpegPhotoLookup', time());
if(!$jpegPhoto || !is_array($jpegPhoto) || !isset($jpegPhoto[0])) {
//not set, nothing left to do;
return;
}
- $image = new \OCP\Image($jpegPhoto[0]);
+ $image = new \OCP\Image();
+ $image->loadFromBase64(base64_encode($jpegPhoto[0]));
+
if(!$image->valid()) {
\OCP\Util::writeLog('user_ldap', 'jpegPhoto data invalid for '.$dn,
\OCP\Util::ERROR);
@@ -103,10 +105,9 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
\OCP\Util::ERROR);
return;
}
-
$avatarManager = \OC::$server->getAvatarManager();
$avatar = $avatarManager->getAvatar($uid);
- $avatar->set($image->data());
+ $avatar->set($image);
}
/**
From 9c4b8ae54c65f109146166b277d99bd4769cc3ec Mon Sep 17 00:00:00 2001
From: Bjoern Schiessle
Date: Mon, 25 Nov 2013 10:29:05 +0100
Subject: [PATCH 17/47] fix typo in comment
---
apps/files_encryption/lib/helper.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index e66a84d909..a844fc6a39 100755
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -256,7 +256,7 @@ class Helper {
$user = \OCP\User::getUser();
- // if we are logged in, than we return the userid
+ // if we are logged in, then we return the userid
if ($user) {
return $user;
}
From 993fea2f05ae300fd1036d2a82ba02413f2649d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20M=C3=BCller?=
Date: Mon, 25 Nov 2013 11:36:33 +0100
Subject: [PATCH 18/47] fix appframework routing
---
lib/private/appframework/app.php | 5 ++++-
.../appframework/routing/routeactionhandler.php | 2 +-
lib/public/appframework/app.php | 11 +++++++++++
3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php
index 6d3effbf1f..7d32403a55 100644
--- a/lib/private/appframework/app.php
+++ b/lib/private/appframework/app.php
@@ -44,7 +44,10 @@ class App {
* @param string $methodName the method that you want to call
* @param DIContainer $container an instance of a pimple container.
*/
- public static function main($controllerName, $methodName, IAppContainer $container) {
+ public static function main($controllerName, $methodName, DIContainer $container, array $urlParams = null) {
+ if (!is_null($urlParams)) {
+ $container['urlParams'] = $urlParams;
+ }
$controller = $container[$controllerName];
// initialize the dispatcher and run all the middleware before the controller
diff --git a/lib/private/appframework/routing/routeactionhandler.php b/lib/private/appframework/routing/routeactionhandler.php
index 7fb56f14ea..2b9dc38dc4 100644
--- a/lib/private/appframework/routing/routeactionhandler.php
+++ b/lib/private/appframework/routing/routeactionhandler.php
@@ -37,6 +37,6 @@ class RouteActionHandler {
}
public function __invoke($params) {
- App::main($this->controllerName, $this->actionName, $params, $this->container);
+ App::main($this->controllerName, $this->actionName, $this->container, $params);
}
}
diff --git a/lib/public/appframework/app.php b/lib/public/appframework/app.php
index 6ac48bf102..1f82f8da88 100644
--- a/lib/public/appframework/app.php
+++ b/lib/public/appframework/app.php
@@ -21,6 +21,7 @@
*/
namespace OCP\AppFramework;
+use OC\AppFramework\routing\RouteConfig;
/**
@@ -47,6 +48,16 @@ class App {
return $this->container;
}
+ /**
+ * This function is to be called
+ * @param \OC_Router $router
+ * @param array $routes
+ */
+ public function registerRoutes($router, $routes) {
+ $routeConfig = new RouteConfig($this->container, $router, $routes);
+ $routeConfig->register();
+ }
+
/**
* This function is called by the routing component to fire up the frameworks dispatch mechanism.
*
From 1fdd2ac7eed9cfd0322e6f17957a083310311470 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20M=C3=BCller?=
Date: Mon, 25 Nov 2013 17:15:08 +0100
Subject: [PATCH 19/47] adding documentation for registerRoutes()
---
lib/public/appframework/app.php | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/lib/public/appframework/app.php b/lib/public/appframework/app.php
index 1f82f8da88..1021a21397 100644
--- a/lib/public/appframework/app.php
+++ b/lib/public/appframework/app.php
@@ -49,7 +49,19 @@ class App {
}
/**
- * This function is to be called
+ * This function is to be called to create single routes and restful routes based on the given $routes array.
+ *
+ * Example code in routes.php of tasks app (it will register two restful resources):
+ * $routes = array(
+ * 'resources' => array(
+ * 'lists' => array('url' => '/tasklists'),
+ * 'tasks' => array('url' => '/tasklists/{listId}/tasks')
+ * )
+ * );
+ *
+ * $a = new TasksApp();
+ * $a->registerRoutes($this, $routes);
+ *
* @param \OC_Router $router
* @param array $routes
*/
From 3955388f204d58dddbd3f787d66f570a0f61855b Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Mon, 25 Nov 2013 22:05:00 +0100
Subject: [PATCH 20/47] LDAP: proxy: configurable return to determine when to
try the next LDAP server and when to return (multi server setup)
---
apps/user_ldap/group_proxy.php | 5 +++--
apps/user_ldap/lib/proxy.php | 7 ++++---
apps/user_ldap/user_proxy.php | 8 +++++---
3 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/apps/user_ldap/group_proxy.php b/apps/user_ldap/group_proxy.php
index acc563c953..4404bd7fe3 100644
--- a/apps/user_ldap/group_proxy.php
+++ b/apps/user_ldap/group_proxy.php
@@ -67,16 +67,17 @@ class Group_Proxy extends lib\Proxy implements \OCP\GroupInterface {
* @param $gid string, the gid connected to the request
* @param $method string, the method of the group backend that shall be called
* @param $parameters an array of parameters to be passed
+ * @param $passOnWhen the result matches this variable
* @return mixed, the result of the method or false
*/
- protected function callOnLastSeenOn($gid, $method, $parameters) {
+ protected function callOnLastSeenOn($gid, $method, $parameters, $passOnWhen) {
$cacheKey = $this->getGroupCacheKey($gid);;
$prefix = $this->getFromCache($cacheKey);
//in case the uid has been found in the past, try this stored connection first
if(!is_null($prefix)) {
if(isset($this->backends[$prefix])) {
$result = call_user_func_array(array($this->backends[$prefix], $method), $parameters);
- if(!$result) {
+ if($result === $passOnWhen) {
//not found here, reset cache to null if group vanished
//because sometimes methods return false with a reason
$groupExists = call_user_func_array(
diff --git a/apps/user_ldap/lib/proxy.php b/apps/user_ldap/lib/proxy.php
index c74b357bdd..30e1875901 100644
--- a/apps/user_ldap/lib/proxy.php
+++ b/apps/user_ldap/lib/proxy.php
@@ -54,7 +54,7 @@ abstract class Proxy {
return 'group-'.$gid.'-lastSeenOn';
}
- abstract protected function callOnLastSeenOn($id, $method, $parameters);
+ abstract protected function callOnLastSeenOn($id, $method, $parameters, $passOnWhen);
abstract protected function walkBackends($id, $method, $parameters);
/**
@@ -64,8 +64,9 @@ abstract class Proxy {
* @param $parameters an array of parameters to be passed
* @return mixed, the result of the specified method
*/
- protected function handleRequest($id, $method, $parameters) {
- if(!$result = $this->callOnLastSeenOn($id, $method, $parameters)) {
+ protected function handleRequest($id, $method, $parameters, $passOnWhen = false) {
+ $result = $this->callOnLastSeenOn($id, $method, $parameters, $passOnWhen);
+ if($result === $passOnWhen) {
$result = $this->walkBackends($id, $method, $parameters);
}
return $result;
diff --git a/apps/user_ldap/user_proxy.php b/apps/user_ldap/user_proxy.php
index 3c2821e87b..b073b143e7 100644
--- a/apps/user_ldap/user_proxy.php
+++ b/apps/user_ldap/user_proxy.php
@@ -54,6 +54,7 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
protected function walkBackends($uid, $method, $parameters) {
$cacheKey = $this->getUserCacheKey($uid);
foreach($this->backends as $configPrefix => $backend) {
+// print("walkBackend '$configPrefix' ");
if($result = call_user_func_array(array($backend, $method), $parameters)) {
$this->writeToCache($cacheKey, $configPrefix);
return $result;
@@ -67,16 +68,17 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
* @param $uid string, the uid connected to the request
* @param $method string, the method of the user backend that shall be called
* @param $parameters an array of parameters to be passed
+ * @param $passOnWhen the result matches this variable
* @return mixed, the result of the method or false
*/
- protected function callOnLastSeenOn($uid, $method, $parameters) {
+ protected function callOnLastSeenOn($uid, $method, $parameters, $passOnWhen) {
$cacheKey = $this->getUserCacheKey($uid);
$prefix = $this->getFromCache($cacheKey);
//in case the uid has been found in the past, try this stored connection first
if(!is_null($prefix)) {
if(isset($this->backends[$prefix])) {
$result = call_user_func_array(array($this->backends[$prefix], $method), $parameters);
- if(!$result) {
+ if($result === $passOnWhen) {
//not found here, reset cache to null if user vanished
//because sometimes methods return false with a reason
$userExists = call_user_func_array(
@@ -169,7 +171,7 @@ class User_Proxy extends lib\Proxy implements \OCP\UserInterface {
* @return boolean either the user can or cannot
*/
public function canChangeAvatar($uid) {
- return $this->handleRequest($uid, 'canChangeAvatar', array($uid));
+ return $this->handleRequest($uid, 'canChangeAvatar', array($uid), true);
}
/**
From 03375d6c522035b108e4cf00239b9705b93dc377 Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Mon, 25 Nov 2013 22:08:11 +0100
Subject: [PATCH 21/47] LDAP: username2dn should only return DNs that belong
to the current LDAP server. Might be not perfect. Easy perfect solution would
increase communication with LDAP server. Let's see if it is good enough
---
apps/user_ldap/lib/access.php | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
index a07bd3fa11..ecc74b6cf5 100644
--- a/apps/user_ldap/lib/access.php
+++ b/apps/user_ldap/lib/access.php
@@ -199,7 +199,9 @@ class Access extends LDAPUtility {
*/
public function username2dn($name) {
$dn = $this->ocname2dn($name, true);
- if($dn) {
+ //Check whether the DN belongs to the Base, to avoid issues on multi-
+ //server setups
+ if($dn && $this->isDNPartOfBase($dn, $this->connection->ldapBaseUsers)) {
return $dn;
}
From 69518b901326617a2a80986df0e250038684563b Mon Sep 17 00:00:00 2001
From: Arthur Schiwon
Date: Tue, 26 Nov 2013 12:57:39 +0100
Subject: [PATCH 22/47] Make sure Avatar is set from LDAP upon first login, not
later, but also not before due to missing user folder
---
apps/user_ldap/user_ldap.php | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index 97fc2fbb6c..527a5c10b8 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -76,8 +76,11 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
* @return void
*/
private function updateAvatar($uid, $dn) {
- $lastChecked = \OCP\Config::getUserValue($uid, 'user_ldap', 'lastJpegPhotoLookup', 0);
- if((time() - $lastChecked) < 86400 ) {
+ $hasLoggedIn = \OCP\Config::getUserValue($uid, 'user_ldap',
+ 'firstLoginAccomplished', 0);
+ $lastChecked = \OCP\Config::getUserValue($uid, 'user_ldap',
+ 'lastJpegPhotoLookup', 0);
+ if(($hasLoggedIn !== '1') || (time() - intval($lastChecked)) < 86400 ) {
//update only once a day
return;
}
@@ -105,6 +108,11 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
\OCP\Util::ERROR);
return;
}
+
+ if(!\OC\Files\Filesystem::$loaded) {
+ \OC_Util::setupFS($uid);
+ }
+
$avatarManager = \OC::$server->getAvatarManager();
$avatar = $avatarManager->getAvatar($uid);
$avatar->set($image);
@@ -160,6 +168,10 @@ class USER_LDAP extends BackendUtility implements \OCP\UserInterface {
return false;
}
+ \OCP\Config::setUserValue($ocname, 'user_ldap',
+ 'firstLoginAccomplished', 1);
+
+ $this->updateAvatar($ocname, $dn);
//give back the display name
return $ocname;
}
From a018dacac2fb8df6f5a92bf005206e0068801890 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 18:39:19 +0100
Subject: [PATCH 23/47] db-doc: appconfig description
---
db_structure.xml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/db_structure.xml b/db_structure.xml
index 377363b7ee..1b72385787 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -9,6 +9,11 @@
+
*dbprefix*appconfig
From 7d1f67b7a95734fc9e703d5c1f32807b04b7c18d Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 18:57:39 +0100
Subject: [PATCH 24/47] db-doc: storages description
---
db_structure.xml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index 1b72385787..46f92fd61c 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -66,7 +66,13 @@
-
+
*dbprefix*storages
From ad603388ca32492d9fd413237b7b5c8b797067c6 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 19:30:59 +0100
Subject: [PATCH 25/47] db-doc: mimetypes description
---
db_structure.xml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index 46f92fd61c..ef161ded50 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -169,7 +169,12 @@
-
+
*dbprefix*mimetypes
From 421a1e69dc61924a3bcfc7302c387c7ed34eac8e Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 20:27:18 +0100
Subject: [PATCH 26/47] db-doc: filecache description
---
db_structure.xml | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index ef161ded50..ba8acaba92 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -210,7 +210,16 @@
-
+
*dbprefix*filecache
@@ -224,6 +233,7 @@
4
+
storage
integer
@@ -248,6 +258,7 @@
32
+
parent
integer
@@ -264,6 +275,7 @@
250
+
mimetype
integer
@@ -272,6 +284,7 @@
4
+
mimepart
integer
From ea2628249329ef2e94cf2613ba12fe79ed7ab856 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 20:27:51 +0100
Subject: [PATCH 27/47] Prettier ASCII lists. ^^
---
db_structure.xml | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/db_structure.xml b/db_structure.xml
index ba8acaba92..623264e32c 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -11,8 +11,8 @@
*dbprefix*appconfig
@@ -68,10 +68,10 @@
*dbprefix*storages
@@ -171,9 +171,9 @@
*dbprefix*mimetypes
From d083108e721cf4bf653ebf5e644da5f02206a895 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 20:41:05 +0100
Subject: [PATCH 28/47] db-doc: permissions description
---
db_structure.xml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index 623264e32c..ab33a488dc 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -395,11 +395,15 @@
-
+
*dbprefix*permissions
+
fileid
integer
@@ -408,6 +412,7 @@
4
+
user
text
From 6da5b05176b8de8d05e2c3e2998d96d4f3d96957 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 20:42:15 +0100
Subject: [PATCH 29/47] Remove the dbprefix from comments. It has no
information.
---
db_structure.xml | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/db_structure.xml b/db_structure.xml
index ab33a488dc..d77e53c915 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -233,7 +233,7 @@
4
-
+
storage
integer
@@ -258,7 +258,7 @@
32
-
+
parent
integer
@@ -275,7 +275,7 @@
250
-
+
mimetype
integer
@@ -284,7 +284,7 @@
4
-
+
mimepart
integer
@@ -403,7 +403,7 @@
-
+
fileid
integer
@@ -412,7 +412,7 @@
4
-
+
user
text
From 46e32b08c0f0e3b4f28ac9961959c4d37b5b17b5 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 20:50:21 +0100
Subject: [PATCH 30/47] db-doc: group_user description
---
db_structure.xml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index d77e53c915..39233a706e 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -446,11 +446,16 @@
-
+
*dbprefix*group_user
+
gid
text
@@ -459,6 +464,7 @@
64
+
uid
text
From 790155e574632c7d628d0bd66cb13764e0cbcdd5 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 20:55:08 +0100
Subject: [PATCH 31/47] db-doc: group_admin description
---
db_structure.xml | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index 39233a706e..f1474fe068 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -492,11 +492,16 @@
-
+
*dbprefix*group_admin
+
gid
text
@@ -505,6 +510,7 @@
64
+
uid
text
From 43f0e3031554f68549887bff49c4dc4f487ad82f Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 20:55:19 +0100
Subject: [PATCH 32/47] db-doc: group_admin reduction note
---
db_structure.xml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/db_structure.xml b/db_structure.xml
index f1474fe068..b99e251525 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -496,6 +496,9 @@
Stores which groups have which users as admins in an n:m relationship.
- Maps group id (gid) to a set of users (uid)
- Maps user id (uid) to a set of groups (gid)
+
+ NOTE: This could (very likely) be reduced to a single bit in group_user
+ instead of repeating varchars gid and uid here
-->
*dbprefix*group_admin
From 466e8985a8702d16605a2cadff711ee1c6cd9cce Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 20:56:05 +0100
Subject: [PATCH 33/47] db-doc: groups description
---
db_structure.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index b99e251525..a55cc18cc7 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -548,7 +548,9 @@
-
+
*dbprefix*groups
From 5450d166b0eb86e583ceef219bf1bf76d90a6178 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 21:15:23 +0100
Subject: [PATCH 34/47] db-doc: locks description
---
db_structure.xml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index a55cc18cc7..34ea742f42 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -577,7 +577,9 @@
-
+
*dbprefix*locks
@@ -592,6 +594,7 @@
4
+
userid
text
From 035199acab332f4c912459eab436a9e18ea94161 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 21:18:18 +0100
Subject: [PATCH 35/47] db-doc: preferences description
---
db_structure.xml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index 34ea742f42..18ec7d4236 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -659,11 +659,16 @@
-
+
*dbprefix*preferences
+
userid
text
From f4031d4320fc2ddbd96b462994d9161c4bd85e17 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 21:23:57 +0100
Subject: [PATCH 36/47] db-doc: properties description
---
db_structure.xml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index 18ec7d4236..9db514bf90 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -722,7 +722,9 @@
-
+
*dbprefix*properties
@@ -736,6 +738,7 @@
4
+
userid
text
From 8cde5e80f632e4b411854d21d819603661c91970 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 21:48:27 +0100
Subject: [PATCH 37/47] db-doc: share description
---
db_structure.xml | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index 9db514bf90..931f9ae42b 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -783,7 +783,9 @@
-
+
*dbprefix*share
@@ -797,6 +799,7 @@
4
+
share_type
integer
@@ -805,6 +808,7 @@
1
+
share_with
text
@@ -813,6 +817,7 @@
255
+
uid_owner
text
@@ -821,6 +826,7 @@
255
+
parent
integer
@@ -828,6 +834,7 @@
4
+
item_type
text
@@ -836,6 +843,7 @@
64
+
item_source
text
@@ -852,6 +860,7 @@
255
+
file_source
integer
@@ -867,6 +876,7 @@
512
+
permissions
integer
@@ -875,6 +885,7 @@
1
+
stime
integer
@@ -883,6 +894,7 @@
8
+
accepted
integer
@@ -891,6 +903,7 @@
1
+
expiration
timestamp
From bc77ba1d4cc5ff88b0f7d6679a4afc293704dd11 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 21:52:30 +0100
Subject: [PATCH 38/47] db-doc: jobs description
---
db_structure.xml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index 931f9ae42b..d08d9f175f 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -957,7 +957,10 @@
-
+
*dbprefix*jobs
From ab773650cdf654f89462751d86646acd4da79a04 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 21:53:55 +0100
Subject: [PATCH 39/47] db-doc: users description
---
db_structure.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index d08d9f175f..8212e4cf73 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -1011,7 +1011,9 @@
-
+
*dbprefix*users
From 2714a22ba855ae96c8d282d3b6cfcd5d281bea66 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 22:06:20 +0100
Subject: [PATCH 40/47] db-doc: vcategory* descriptions
---
db_structure.xml | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/db_structure.xml b/db_structure.xml
index 8212e4cf73..aa5c134009 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -1055,7 +1055,9 @@
-
+
*dbprefix*vcategory
@@ -1070,6 +1072,7 @@
4
+
uid
text
@@ -1122,7 +1125,9 @@
-
+
*dbprefix*vcategory_to_object
@@ -1136,6 +1141,7 @@
4
+
categoryid
integer
From 68986f52725536a6cb64e0c0310614c90e1945b6 Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 22:13:01 +0100
Subject: [PATCH 41/47] db-doc: privatedata description
---
db_structure.xml | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/db_structure.xml b/db_structure.xml
index aa5c134009..7de0f9234b 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -1194,7 +1194,11 @@
-
+
*dbprefix*privatedata
@@ -1209,6 +1213,7 @@
1
+
user
text
From 0013e2e6a8d9adcc8578858aa07a18abd159be1b Mon Sep 17 00:00:00 2001
From: Andreas Fischer
Date: Tue, 26 Nov 2013 22:16:14 +0100
Subject: [PATCH 42/47] Fix spacing.
---
db_structure.xml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/db_structure.xml b/db_structure.xml
index 7de0f9234b..db817faece 100644
--- a/db_structure.xml
+++ b/db_structure.xml
@@ -66,6 +66,7 @@