diff --git a/UI/AdministrationUI/GNUmakefile b/UI/AdministrationUI/GNUmakefile index 450973525..1034a8b17 100644 --- a/UI/AdministrationUI/GNUmakefile +++ b/UI/AdministrationUI/GNUmakefile @@ -12,6 +12,7 @@ AdministrationUI_OBJC_FILES = \ AdministrationUIProduct.m \ \ UIxAdministration.m \ + UIxAdministrationAclEditor.m \ UIxAdministrationFilterPanel.m AdministrationUI_RESOURCE_FILES += \ diff --git a/UI/AdministrationUI/UIxAdministrationAclEditor.h b/UI/AdministrationUI/UIxAdministrationAclEditor.h new file mode 100644 index 000000000..08d24d431 --- /dev/null +++ b/UI/AdministrationUI/UIxAdministrationAclEditor.h @@ -0,0 +1,48 @@ +/* UIxAdministrationAclEditor.h - this file is part of SOGo + * + * Copyright (C) 2006-2014 Inverse inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef UIXACLEDITOR_H +#define UIXACLEDITOR_H + +#import + +@interface UIxAdministrationAclEditor : UIxComponent +{ + BOOL prepared; + BOOL publishInFreeBusy; + NSArray *aclUsers; + NSArray *savedUIDs; + NSMutableDictionary *users; + NSString *currentUser; + NSString *defaultUserID; +} + +- (NSArray *) aclsForObject; +- (void) setCurrentUser: (NSString *) newCurrentUser; +- (NSString *) currentUser; +- (NSString *) currentUserClass; +- (NSDictionary *) currentUserInfos; +- (NSString *) currentUserDisplayName; +- (BOOL) currentUserIsSubscribed; +- (BOOL) isPublicAccessEnabled; + +@end + +#endif /* UIXACLEDITOR_H */ diff --git a/UI/AdministrationUI/UIxAdministrationAclEditor.m b/UI/AdministrationUI/UIxAdministrationAclEditor.m new file mode 100644 index 000000000..9370aa34a --- /dev/null +++ b/UI/AdministrationUI/UIxAdministrationAclEditor.m @@ -0,0 +1,279 @@ +/* UIxAdministrationAclEditor.m - this file is part of SOGo + * + * Copyright (C) 2006-2015 Inverse inc. + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import +#import +#import +#import + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import "UIxAdministrationAclEditor.h" + +@implementation UIxAdministrationAclEditor + +- (id) init +{ + if ((self = [super init])) + { + aclUsers = nil; + prepared = NO; + publishInFreeBusy = NO; + users = [NSMutableDictionary new]; + currentUser = nil; + defaultUserID = nil; + savedUIDs = nil; + } + + return self; +} + +- (void) dealloc +{ + [savedUIDs release]; + [users release]; + [currentUser release]; + [defaultUserID release]; + [super dealloc]; +} + +- (NSArray *) aclsForObject +{ + if (!aclUsers) + aclUsers = [[self clientObject] aclUsers]; + + return aclUsers; +} + +- (NSString *) defaultUserID +{ + if (!defaultUserID) + ASSIGN (defaultUserID, [[self clientObject] defaultUserID]); + + return defaultUserID; +} + +- (BOOL) canSubscribeUsers +{ + return [[self clientObject] + respondsToSelector: @selector (subscribeUserOrGroup:reallyDo:response:)]; +} + +/** + * @api {get} /so/:username/:folderPath/acls List users with rights + * @apiVersion 1.0.0 + * @apiName GetAcls + * @apiGroup Common + * @apiExample {curl} Example usage: + * curl -i http://localhost/SOGo/so/sogo1/Calendar/personal/acls + * + * @apiSuccess (Success 200) {Object[]} users List of users with ACL for the folder + * @apiSuccess (Success 200) {String} users.uid User ID + * @apiSuccess (Success 200) {String} users.userClass Either 'normal-user', 'normal-group' or 'public-access' + * @apiSuccess (Success 200) {Number} users.isSubscribed 1 if the user is subscribed to the folder + * @apiSuccess (Success 200) {String} [users.cn] User fullname + * @apiSuccess (Success 200) {String} [users.c_email] User main email address + */ +- (id ) aclsAction +{ + NSString *currentUID, *ownerLogin, *info; + NSDictionary *currentUserInfos; + NSMutableDictionary *userData; + id result; + NSEnumerator *aclsEnum; + + if (!prepared) + { + ownerLogin = [[self clientObject] ownerInContext: context]; + if (!defaultUserID) + ASSIGN (defaultUserID, [[self clientObject] defaultUserID]); + + aclsEnum = [[self aclsForObject] objectEnumerator]; + while ((currentUID = [aclsEnum nextObject])) + { + if (!([currentUID isEqualToString: ownerLogin] + || [currentUID isEqualToString: defaultUserID] + || [currentUID isEqualToString: @"anonymous"])) + { + // Set the current user in order to get information associated with it + [self setCurrentUser: currentUID]; + + // Build the object associated to the current UID + currentUserInfos = [self currentUserInfos]; + userData = [NSMutableDictionary dictionaryWithObjectsAndKeys: + currentUser, @"uid", + [self currentUserClass], @"userClass", + [NSNumber numberWithBool: [self currentUserIsSubscribed]], @"isSubscribed", + nil]; + if ((info = [currentUserInfos objectForKey: @"cn"]) && [info length]) + [userData setObject: info forKey: @"cn"]; + if ((info = [currentUserInfos objectForKey: @"c_email"]) && [info length]) + [userData setObject: info forKey: @"c_email"]; + [users setObject: userData forKey: currentUID]; + } + } + + // Add the 'Any authenticated' user + if ([self canSubscribeUsers]) + { + userData = [NSDictionary dictionaryWithObjectsAndKeys: + @"", @"uid", + [self labelForKey: @"Any Authenticated User"], @"cn", + @"public-user", @"userClass", + nil]; + [users setObject: userData forKey: @""]; + } + + if ([self canSubscribeUsers] && [self isPublicAccessEnabled]) + { + // Add the 'public access' user + userData = [NSDictionary dictionaryWithObjectsAndKeys: + @"anonymous", @"uid", + [self labelForKey: @"Public Access"], @"cn", + @"public-user", @"userClass", + nil]; + [users setObject: userData forKey: @"anonymous"]; + } + + prepared = YES; + } + + result = [self responseWithStatus: 200 + andJSONRepresentation: [NSDictionary dictionaryWithObject: users forKey: @"users"]]; + + return result; +} + +- (void) setCurrentUser: (NSString *) newCurrentUser +{ + ASSIGN (currentUser, newCurrentUser); +} + +- (NSString *) currentUser +{ + return ([currentUser hasPrefix: @"@"] + ? [currentUser substringFromIndex: 1] + : currentUser); +} + +- (NSString *) currentUserClass +{ + return ([currentUser hasPrefix: @"@"] + ? @"normal-group" + : @"normal-user"); +} + +- (NSString *) currentUserDisplayName +{ + NSDictionary *infos; + NSString *uid; + SOGoUserManager *um; + + um = [SOGoUserManager sharedUserManager]; + uid = [self currentUser]; + infos = [um contactInfosForUserWithUIDorEmail: uid inDomain: [[context activeUser] domain]]; + if (infos) + { + return [NSString stringWithFormat: @"%@ <%@>", + [infos objectForKey: @"cn"], + [infos objectForKey: @"c_email"]]; + } + else + return uid; +} + +- (NSDictionary *) currentUserInfos +{ + SOGoUserManager *um; + + um = [SOGoUserManager sharedUserManager]; + + return [um contactInfosForUserWithUIDorEmail: [self currentUser]]; +} + +- (BOOL) currentUserIsSubscribed +{ + SOGoGCSFolder *folder; + + folder = [self clientObject]; + + return ([folder respondsToSelector: @selector (userIsSubscriber:)] + && [folder userIsSubscriber: currentUser]); +} + +- (void) setUserUIDS: (NSString *) retainedUsers +{ + if ([retainedUsers length] > 0) + { + savedUIDs = [retainedUsers componentsSeparatedByString: @","]; + [savedUIDs retain]; + } + else + savedUIDs = [NSArray new]; +} + +- (NSString *) folderID +{ + return [[self clientObject] nameInContainer]; +} + +- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request + inContext: (WOContext *) context +{ + return ([[request method] isEqualToString: @"POST"]); +} + +- (id ) saveAclsAction +{ + NSEnumerator *aclsEnum; + SOGoObject *clientObject; + NSString *currentUID, *ownerLogin; + + clientObject = [self clientObject]; + ownerLogin = [clientObject ownerInContext: context]; + aclsEnum = [[self aclsForObject] objectEnumerator]; + while ((currentUID = [[aclsEnum nextObject] objectForKey: @"c_uid"])) + if ([currentUID isEqualToString: ownerLogin] + || [savedUIDs containsObject: currentUID]) + [users removeObjectForKey: currentUID]; + [clientObject removeAclsForUsers: [users allKeys]]; + + return [self jsCloseWithRefreshMethod: nil]; +} + +- (BOOL) isPublicAccessEnabled +{ + return [[SOGoSystemDefaults sharedSystemDefaults] enablePublicAccess]; +} + +@end diff --git a/UI/AdministrationUI/product.plist b/UI/AdministrationUI/product.plist index bfb7ae21c..28dd5ed15 100644 --- a/UI/AdministrationUI/product.plist +++ b/UI/AdministrationUI/product.plist @@ -15,6 +15,10 @@ protectedBy = "View"; pageName = "UIxAdministration"; }; + UIxAdministrationAclEditor = { + protectedBy = "View"; + pageName = "UIxAdministrationAclEditor"; + }; }; }; }; diff --git a/UI/MainUI/SOGoUserHomePage.m b/UI/MainUI/SOGoUserHomePage.m index fb770a23f..d8e956cca 100644 --- a/UI/MainUI/SOGoUserHomePage.m +++ b/UI/MainUI/SOGoUserHomePage.m @@ -636,7 +636,7 @@ * @apiExample {curl} Example usage: * curl -i http://localhost/SOGo/so/sogo1/foldersSearch?type=contact * - * @apiParam {String} type Either 'calendar' or 'contact' + * @apiParam {String} type Either 'calendar' or 'contact'. If nothing is specifed, its both. * * @apiSuccess (Success 200) {Object[]} folders List of matching folders * @apiSuccess (Success 200) {String} folders.name Path of folder @@ -648,27 +648,31 @@ - (id ) foldersSearchAction { NSString *folderType; - NSArray *folders; + NSMutableArray *folders; NSDictionary *message; id result; SOGoUserFolder *userFolder; folderType = [self queryParameterForKey: @"type"]; + folders = [NSMutableArray array]; + userFolder = [self clientObject]; + if ([folderType length]) { - userFolder = [self clientObject]; - folders = [userFolder foldersOfType: folderType - forUID: [userFolder ownerInContext: context]]; - result = [self _foldersResponseForResults: folders]; + [folders addObjectsFromArray: [userFolder foldersOfType: folderType + forUID: [userFolder ownerInContext: context]]]; } else { - message = [NSDictionary dictionaryWithObject: [self labelForKey: @"Missing type parameter"] - forKey: @"error"]; - result = [self responseWithStatus: 400 andJSONRepresentation: message]; + [folders addObjectsFromArray: [userFolder foldersOfType: @"calendar" + forUID: [userFolder ownerInContext: context]]]; + [folders addObjectsFromArray: [userFolder foldersOfType: @"contact" + forUID: [userFolder ownerInContext: context]]]; } + result = [self _foldersResponseForResults: folders]; + return result; } diff --git a/UI/Scheduler/product.plist b/UI/Scheduler/product.plist index e8dabb3af..4a344f2e9 100644 --- a/UI/Scheduler/product.plist +++ b/UI/Scheduler/product.plist @@ -182,6 +182,10 @@ actionClass = "UIxCalFolderActions"; actionName = "import"; }; + UIxCalUserRightsEditor = { + protectedBy = "ReadAcls"; + pageName = "UIxCalUserRightsEditor"; + }; userRights = { protectedBy = "ReadAcls"; pageName = "UIxCalUserRightsEditor"; diff --git a/UI/Templates/AdministrationUI/UIxAdministration.wox b/UI/Templates/AdministrationUI/UIxAdministration.wox index 18713a063..2f3249359 100644 --- a/UI/Templates/AdministrationUI/UIxAdministration.wox +++ b/UI/Templates/AdministrationUI/UIxAdministration.wox @@ -7,7 +7,9 @@ xmlns:label="OGo:label" className="UIxPageFrame" title="title" - const:jsFiles="Common.js, Administration.js, Administration.services.js, Contacts.services.js"> + const:jsFiles="Common.js, Administration.js, + Administration.services.js, Preferences.services.js, + Contacts.services.js, Scheduler.services.js">
@@ -28,18 +30,7 @@ -
- - - -
- -
-
- -
-
-
+
@@ -47,11 +38,79 @@ RIGHTS ADMINISTRATION PANEL --> + + +
+ +
+
+
+ +
+ + +
+ + search + + + + +
+
+ + + + + +
+ +
+ +
+
+
+
+
{{user.cn}}
+
{{user.c_email}}
+
+ expand_more +
+
+ +
+ warning + +
+
+ + {{folder.displayName}} +
+
+
+
+
+ +
+ + + + + + +
+
+ diff --git a/UI/WebServerResources/js/Administration/Administration.app.js b/UI/WebServerResources/js/Administration/Administration.app.js index f5cd609fd..ff9a7e69c 100644 --- a/UI/WebServerResources/js/Administration/Administration.app.js +++ b/UI/WebServerResources/js/Administration/Administration.app.js @@ -4,7 +4,7 @@ (function() { 'use strict'; - angular.module('SOGo.AdministrationUI', ['ngSanitize', 'ui.router', 'SOGo.Common', 'SOGo.ContactsUI', 'SOGo.Authentication']) + angular.module('SOGo.AdministrationUI', ['ngSanitize', 'ui.router', 'SOGo.Common', 'SOGo.Authentication', 'SOGo.PreferencesUI', 'SOGo.ContactsUI', 'SOGo.SchedulerUI']) .config(configure) .run(runBlock); @@ -22,9 +22,6 @@ controller: 'AdministrationController', controllerAs: 'app' } - }, - resolve: { - stateAdministration: stateAdministration } }) .state('administration.rights', { @@ -34,18 +31,48 @@ templateUrl: 'rights.html' } } + }) + .state('administration.rights.edit', { + url: '/:userId/:folderId/edit', + views: { + acl: { + templateUrl: 'UIxAdministrationAclEditor', // UI/Templates/Administration/UIxAdministrationAclEditor.wox + controller: 'AdministrationAclController', + controllerAs: 'acl' + } + }, + resolve: { + stateFolder: stateFolder + } }); // if none of the above states are matched, use this as the fallback $urlRouterProvider.otherwise('/rights'); } + + stateFolder.$inject = ['$stateParams', 'User', 'AddressBook', 'Calendar']; + function stateFolder($stateParams, User, AddressBook, Calendar) { + var user = _.find(User.$users, function(user) { + return user.uid == $stateParams.userId; + }); - /** - * @ngInject - */ - stateAdministration.$inject = ['Administration']; - function stateAdministration(Administration) { - return Administration; + var folder = _.find(user.$$folders, function(folder) { + return folder.name == $stateParams.folderId; + }); + + var o; + + if (folder.type == "Appointment") { + o = new Calendar({id: folder.name.split('/').pop(), + owner: folder.owner, + name: folder.displayName}); + } else { + o = new AddressBook({id: folder.name.split('/').pop(), + owner: folder.owner, + name: folder.displayName}); + } + + return o; } /** diff --git a/UI/WebServerResources/js/Administration/AdministrationAclController.js b/UI/WebServerResources/js/Administration/AdministrationAclController.js new file mode 100644 index 000000000..64c4e7427 --- /dev/null +++ b/UI/WebServerResources/js/Administration/AdministrationAclController.js @@ -0,0 +1,79 @@ +/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* JavaScript for SOGoAdministration */ + +(function() { + 'use strict'; + + /** + * @ngInject + */ + AdministrationAclController.$inject = ['$state', '$mdToast', 'stateFolder', 'User']; + function AdministrationAclController($state, $mdToast, stateFolder, User) { + var vm = this; + + vm.selectedUser = null; + vm.getTemplate = getTemplate; + vm.selectUser = selectUser; + vm.save = save; + + vm.userToAdd = ''; + vm.searchText = ''; + vm.userFilter = userFilter; + vm.addUser = addUser; + + stateFolder.$acl.$users(stateFolder.owner).then(function(data) { + vm.users = data; + }); + + function getTemplate() { + if (angular.isDefined(stateFolder.$cards)) + return '../' + stateFolder.owner + '/Contacts/' + stateFolder.id + '/UIxContactsUserRightsEditor'; + + return '../' + stateFolder.owner + '/Calendar/' + stateFolder.id + '/UIxCalUserRightsEditor'; + } + + function selectUser(user) { + if (vm.selectedUser == user) { + vm.selectedUser = null; + } + else { + vm.selectedUser = user; + vm.selectedUser.$rights(); + } + } + + function userFilter($query) { + return User.$filter($query, stateFolder.$acl.users); + } + + function addUser(data) { + if (data) { + stateFolder.$acl.$addUser(data, stateFolder.owner).then(function() { + vm.userToAdd = ''; + vm.searchText = ''; + }, function(error) { + Dialog.alert(l('Warning'), error); + }); + } + } + + function save() { + stateFolder.$acl.$saveUsersRights(stateFolder.owner).then(function() { + $mdToast.show( + $mdToast.simple() + .content(l('ACLs saved')) + .position('top right') + .hideDelay(3000) + ); + }, function(data, status) { + Dialog.alert(l('Warning'), l('An error occured please try again.')); + }); + } + + } + + angular + .module('SOGo.AdministrationUI') + .controller('AdministrationAclController', AdministrationAclController); + +})(); diff --git a/UI/WebServerResources/js/Administration/AdministrationController.js b/UI/WebServerResources/js/Administration/AdministrationController.js index 675335423..de9a4e6ee 100644 --- a/UI/WebServerResources/js/Administration/AdministrationController.js +++ b/UI/WebServerResources/js/Administration/AdministrationController.js @@ -7,18 +7,45 @@ /** * @ngInject */ - AdministrationController.$inject = ['$state', '$mdDialog', '$mdToast', 'Dialog', 'User', 'stateAdministration', 'Authentication']; - function AdministrationController($state, $mdDialog, $mdToast, Dialog, User, stateAdministration, Authentication) { + AdministrationController.$inject = ['$state', '$mdDialog', '$mdToast', 'Dialog', 'User', 'Administration']; + function AdministrationController($state, $mdDialog, $mdToast, Dialog, User, Administration) { var vm = this; - vm.administration = stateAdministration; + vm.administration = Administration; + + vm.selectedUser = null; + vm.users = User.$users; vm.go = go; - + vm.filter = filter; + vm.selectUser = selectUser; + vm.selectFolder = selectFolder; + function go(module) { $state.go('administration.' + module); } + function filter(searchText) { + User.$filter(searchText).then(function() { + }); + } + + function selectUser(i) { + if (vm.selectedUser == vm.users[i]) { + vm.selectedUser = null; + } + else { + // Fetch folders of specific type for selected user + vm.users[i].$folders().then(function() { + vm.selectedUser = vm.users[i]; + }); + } + } + + function selectFolder(folder) { + $state.go('administration.rights.edit', {userId: vm.selectedUser.uid, folderId: folder.name}); + } + } angular diff --git a/UI/WebServerResources/js/Common/Acl.service.js b/UI/WebServerResources/js/Common/Acl.service.js index 678ce5c59..bc140450a 100644 --- a/UI/WebServerResources/js/Common/Acl.service.js +++ b/UI/WebServerResources/js/Common/Acl.service.js @@ -35,10 +35,11 @@ /** * @function $users * @memberof Acl.prototype + * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser * @desc Fetch the list of users that have specific rights for the current folder. * @return a promise of an array of User objects */ - Acl.prototype.$users = function() { + Acl.prototype.$users = function(owner) { var _this = this, deferred = Acl.$q.defer(), user; @@ -46,14 +47,20 @@ deferred.resolve(this.users); } else { - return Acl.$$resource.fetch(this.folderId, 'acls').then(function(response) { + var acls; + if (angular.isDefined(owner)) + acls = Acl.$$resource.userResource(owner).fetch(this.folderId, 'acls'); + else + acls = Acl.$$resource.fetch(this.folderId, 'acls'); + + return acls.then(function(response) { _this.users = []; //console.debug(JSON.stringify(users, undefined, 2)); angular.forEach(response.users, function(data) { user = new Acl.$User(data); user.canSubscribeUser = user.isSubscribed; user.wasSubscribed = user.isSubscribed; - user.$rights = angular.bind(user, user.$acl, _this.folderId); + user.$rights = angular.bind(user, user.$acl, _this.folderId, owner); _this.users.push(user); }); deferred.resolve(_this.users); @@ -67,9 +74,10 @@ * @function $addUser * @memberof Acl.prototype * @param {Object} user - a User object with minimal set of attributes (uid, isGroup, cn, c_email) + * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser * @see {@link User.$filter} */ - Acl.prototype.$addUser = function(user) { + Acl.prototype.$addUser = function(user, owner) { var _this = this, deferred = Acl.$q.defer(), param = {uid: user.uid}; @@ -78,7 +86,14 @@ deferred.resolve(); } else { - Acl.$$resource.fetch(this.folderId, 'addUserInAcls', param).then(function() { + var acls; + + if (angular.isDefined(owner)) + acls = Acl.$$resource.userResource(owner).fetch(this.folderId, 'addUserInAcls', param); + else + acls = Acl.$$resource.fetch(this.folderId, 'addUserInAcls', param); + + acls.then(function() { user.wasSubscribed = false; user.userClass = user.isGroup ? 'group-user' : 'normal-user'; user.$rights = angular.bind(user, user.$acl, _this.folderId); @@ -123,9 +138,10 @@ * @function $saveUsersRights * @memberof Acl.prototype * @desc Save user rights that have changed and subscribe users that have been selected. + * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser * @return a promise that resolved only if the modifications and subscriptions were successful */ - Acl.prototype.$saveUsersRights = function() { + Acl.prototype.$saveUsersRights = function(owner) { var _this = this, deferredSave = Acl.$q.defer(), deferredSubscribe = Acl.$q.defer(), @@ -140,8 +156,14 @@ } }); if (users.length) { - Acl.$$resource.save(this.folderId, users, param) - .then(function() { + var acls; + + if (angular.isDefined(owner)) + acls = Acl.$$resource.userResource(owner).save(this.folderId, users, param); + else + acls = Acl.$$resource.save(this.folderId, users, param); + + acls.then(function() { // Save was successful; copy rights to shadow rights angular.forEach(_this.users, function(user) { if (user.$rightsAreDirty()) { diff --git a/UI/WebServerResources/js/Common/User.service.js b/UI/WebServerResources/js/Common/User.service.js index b6da0b875..0ec9e3f4b 100644 --- a/UI/WebServerResources/js/Common/User.service.js +++ b/UI/WebServerResources/js/Common/User.service.js @@ -128,9 +128,10 @@ * @memberof User.prototype * @desc Fetch the user rights associated to a specific folder and populate the 'rights' attribute. * @param {string} the folder ID + * @param {Object} owner - the owner to use when fetching the ACL as it might not be the Settings.activeUser * @return a promise */ - User.prototype.$acl = function(folderId) { + User.prototype.$acl = function(folderId, owner) { var _this = this, deferred = User.$q.defer(), param = {uid: this.uid}; @@ -138,7 +139,14 @@ deferred.resolve(this.rights); } else { - User.$$resource.fetch(folderId, 'userRights', param).then(function(data) { + var rights; + + if (angular.isDefined(owner)) + rights = User.$$resource.userResource(owner).fetch(folderId, 'userRights', param); + else + rights = User.$$resource.fetch(folderId, 'userRights', param); + + rights.then(function(data) { _this.rights = data; // Convert numbers (0|1) to boolean values //angular.forEach(_.keys(_this.rights), function(key) {