Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>tags/v14.0.0beta1
@@ -90,12 +90,12 @@ abstract class AUserData extends OCSController { | |||
} | |||
// Should be at least Admin Or SubAdmin! | |||
if( $this->groupManager->isAdmin($currentLoggedInUser->getUID()) | |||
if ($this->groupManager->isAdmin($currentLoggedInUser->getUID()) | |||
|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) { | |||
$data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true') === 'true'; | |||
} else { | |||
// Check they are looking up themselves | |||
if($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) { | |||
if ($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) { | |||
return $data; | |||
} | |||
} |
@@ -207,6 +207,10 @@ class GroupsController extends AUserData { | |||
// Do not insert empty entry | |||
if(!empty($userData)) { | |||
$usersDetails[$userId] = $userData; | |||
} else { | |||
// Logged user does not have permissions to see this user | |||
// only showing its id | |||
$usersDetails[$userId] = ['id' => $userId]; | |||
} | |||
} | |||
return new DataResponse(['users' => $usersDetails]); |
@@ -180,6 +180,10 @@ class UsersController extends AUserData { | |||
// Do not insert empty entry | |||
if (!empty($userData)) { | |||
$usersDetails[$userId] = $userData; | |||
} else { | |||
// Logged user does not have permissions to see this user | |||
// only showing its id | |||
$usersDetails[$userId] = ['id' => $userId]; | |||
} | |||
} | |||
@@ -187,34 +187,34 @@ class UsersController extends Controller { | |||
list($adminGroup, $groups) = $groupsInfo->get(); | |||
if ($this->isAdmin) { | |||
$subAdmins = $this->groupManager->getSubAdmin()->getAllSubAdmins(); | |||
// New class returns IUser[] so convert back | |||
$result = []; | |||
foreach ($subAdmins as $subAdmin) { | |||
$result[] = [ | |||
'gid' => $subAdmin['group']->getGID(), | |||
'uid' => $subAdmin['user']->getUID(), | |||
]; | |||
} | |||
$subAdmins = $result; | |||
$disabledUsers = $isLDAPUsed ? 0 : $this->userManager->countDisabledUsers(); | |||
$userCount = array_reduce($this->userManager->countUsers(), function($v, $w) { | |||
return $v + (int)$w; | |||
}, 0); | |||
} else { | |||
/* Retrieve group IDs from $groups array, so we can pass that information into OC_Group::displayNamesInGroups() */ | |||
$gids = array(); | |||
foreach($groups as $group) { | |||
if (isset($group['id'])) { | |||
$gids[] = $group['id']; | |||
// User is subadmin ! | |||
// TODO We can't have the total user count per groups, disabling it | |||
$userCount = false; | |||
$groupsNames = []; | |||
// Map group list to names to retrieve the countDisabledUsersOfGroups | |||
$userGroups = $this->groupManager->getUserGroupIds($user); | |||
foreach($groups as $key => $group) { | |||
// $userCount += (int)$group['usercount']; | |||
array_push($groupsNames, $group['name']); | |||
// we prevent subadmins from looking up themselves | |||
// so we lower the count of the groups he belongs to | |||
if (in_array($group['id'], $userGroups)) { | |||
$groups[$key]['usercount']--; | |||
} | |||
} | |||
$subAdmins = false; | |||
}; | |||
$disabledUsers = $isLDAPUsed ? 0 : $this->userManager->countDisabledUsersOfGroups($groupsNames); | |||
} | |||
$disabledUsers = $isLDAPUsed ? 0 : $this->userManager->countDisabledUsers(); | |||
$disabledUsersGroup = [ | |||
'id' => 'disabled', | |||
'name' => 'Disabled users', | |||
'usercount' => $disabledUsers | |||
]; | |||
$allGroups = array_merge_recursive($adminGroup, $groups); | |||
/* QUOTAS PRESETS */ | |||
$quotaPreset = $this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'); | |||
@@ -227,11 +227,6 @@ class UsersController extends Controller { | |||
\OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts'); | |||
/* TOTAL USERS COUNT */ | |||
$userCount = array_reduce($this->userManager->countUsers(), function($v, $w) { | |||
return $v + (int)$w; | |||
}, 0); | |||
/* LANGUAGES */ | |||
$languages = $this->l10nFactory->getLanguages(); | |||
@@ -241,10 +236,9 @@ class UsersController extends Controller { | |||
$serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups); | |||
// Various data | |||
$serverData['isAdmin'] = $this->isAdmin; | |||
$serverData['subadmins'] = $subAdmins; | |||
$serverData['sortGroups'] = $sortGroupsBy; | |||
$serverData['quotaPreset'] = $quotaPreset; | |||
$serverData['userCount'] = $userCount-$disabledUsers; | |||
$serverData['userCount'] = $userCount === false ? false : $userCount - $disabledUsers; | |||
$serverData['languages'] = $languages; | |||
$serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en'); | |||
// Settings |
@@ -1320,6 +1320,10 @@ doesnotexist:-o-prefocus, .strengthify-wrapper { | |||
.userActions { | |||
width: 100px; | |||
} | |||
.obfuscated { | |||
width: 400px; | |||
opacity: .7; | |||
} | |||
&#grid-header, | |||
&#new-user { | |||
position: sticky; |
@@ -1,21 +1,16 @@ | |||
<template> | |||
<li :id="item.id" :class="[{'icon-loading-small': item.loading, 'open': item.opened, 'collapsible': item.collapsible&&item.children&&item.children.length>0 }, item.classes]"> | |||
<router-link :to="item.router" tag="li" :id="item.id" exact | |||
:class="[{'icon-loading-small': item.loading, 'open': item.opened, 'collapsible': item.collapsible&&item.children&&item.children.length>0 }, item.classes]"> | |||
<!-- Bullet --> | |||
<div v-if="item.bullet" class="app-navigation-entry-bullet" :style="{ backgroundColor: item.bullet }"></div> | |||
<!-- Main link --> | |||
<a v-if="item.href" :href="(item.href) ? item.href : '#' " @click="toggleCollapse" :class="item.icon" > | |||
<a :href="(item.href) ? item.href : '#' " @click="toggleCollapse" :class="item.icon"> | |||
<img v-if="item.iconUrl" :alt="item.text" :src="item.iconUrl"> | |||
{{item.text}} | |||
</a> | |||
<!-- Router link if specified. href OR router --> | |||
<router-link :to="item.router" v-else-if="item.router" :class="item.icon" > | |||
<img v-if="item.iconUrl" :alt="item.text" :src="item.iconUrl"> | |||
{{item.text}} | |||
</router-link> | |||
<!-- Popover, counter and button(s) --> | |||
<div v-if="item.utils" class="app-navigation-entry-utils"> | |||
<ul> | |||
@@ -69,7 +64,7 @@ | |||
<ul v-if="item.children"> | |||
<navigation-item v-for="(item, key) in item.children" :item="item" :key="key" /> | |||
</ul> | |||
</li> | |||
</router-link> | |||
</template> | |||
<script> |
@@ -171,7 +171,7 @@ export default { | |||
}, | |||
filteredUsers() { | |||
if (this.selectedGroup === 'disabled') { | |||
let disabledUsers = this.users.filter(user => user.enabled !== true); | |||
let disabledUsers = this.users.filter(user => user.enabled === false); | |||
if (disabledUsers.length===0 && this.$refs.infiniteLoading && this.$refs.infiniteLoading.isComplete) { | |||
// disabled group is empty, redirection to all users | |||
this.$router.push({name: 'users'}); | |||
@@ -179,7 +179,7 @@ export default { | |||
} | |||
return disabledUsers; | |||
} | |||
return this.users.filter(user => user.enabled === true); | |||
return this.users.filter(user => user.enabled !== false); | |||
}, | |||
groups() { | |||
// data provided php side + remove the disabled group |
@@ -1,5 +1,17 @@ | |||
<template> | |||
<div class="row" :class="{'disabled': loading.delete || loading.disable}"> | |||
<!-- Obfuscated user: Logged in user does not have permissions to see all of the data --> | |||
<div class="row" v-if="Object.keys(user).length ===1"> | |||
<div class="avatar" :class="{'icon-loading-small': loading.delete || loading.disable}"> | |||
<img alt="" width="32" height="32" :src="generateAvatar(user.id, 32)" | |||
:srcset="generateAvatar(user.id, 64)+' 2x, '+generateAvatar(user.id, 128)+' 4x'" | |||
v-if="!loading.delete && !loading.disable"> | |||
</div> | |||
<div class="name">{{user.id}}</div> | |||
<div class="obfuscated">{{t('settings','You do not have permissions to see the details of this user')}}</div> | |||
</div> | |||
<!-- User full data --> | |||
<div class="row" v-else :class="{'disabled': loading.delete || loading.disable}"> | |||
<div class="avatar" :class="{'icon-loading-small': loading.delete || loading.disable}"> | |||
<img alt="" width="32" height="32" :src="generateAvatar(user.id, 32)" | |||
:srcset="generateAvatar(user.id, 64)+' 2x, '+generateAvatar(user.id, 128)+' 4x'" |
@@ -18,6 +18,7 @@ export default new Router({ | |||
// if index.php is in the url AND we got this far, then it's working: | |||
// let's keep using index.php in the url | |||
base: OC.generateUrl(''), | |||
linkActiveClass: 'active', | |||
routes: [ | |||
{ | |||
path: '/:index(index.php/)?settings/users', |
@@ -10,7 +10,11 @@ const debug = process.env.NODE_ENV !== 'production'; | |||
const mutations = { | |||
API_FAILURE(state, error) { | |||
let message = error.error.response.data.ocs.meta.message; | |||
try { | |||
let message = error.error.response.data.ocs.meta.message; | |||
} catch(e) { | |||
let message = error; | |||
} | |||
OC.Notification.showHtml(t('settings','An error occured during the request. Unable to proceed.')+'<br>'+message, {timeout: 7}); | |||
console.log(state, error); | |||
} |
@@ -12,6 +12,15 @@ const orderGroups = function(groups, orderBy) { | |||
} | |||
}; | |||
const defaults = { | |||
group: { | |||
id: '', | |||
name: '', | |||
usercount: 0, | |||
disabled: 0 | |||
} | |||
} | |||
const state = { | |||
users: [], | |||
groups: [], | |||
@@ -33,18 +42,20 @@ const mutations = { | |||
state.minPasswordLength = length!=='' ? length : 0; | |||
}, | |||
initGroups(state, {groups, orderBy, userCount}) { | |||
state.groups = groups; | |||
state.groups = groups.map(group => Object.assign({}, defaults.group, group)); | |||
state.orderBy = orderBy; | |||
state.userCount = userCount; | |||
state.groups = orderGroups(state.groups, state.orderBy); | |||
}, | |||
addGroup(state, gid) { | |||
try { | |||
state.groups.push({ | |||
// extend group to default values | |||
let group = Object.assign({}, defaults.group, { | |||
id: gid, | |||
name: gid, | |||
usercount: 0 // user will be added after the creation | |||
name: gid | |||
}); | |||
state.groups.push(group); | |||
state.groups = orderGroups(state.groups, state.orderBy); | |||
} catch (e) { | |||
console.log('Can\'t create group', e); | |||
@@ -90,11 +101,15 @@ const mutations = { | |||
state.users.push(response.data.ocs.data); | |||
}, | |||
enableDisableUser(state, { userid, enabled }) { | |||
state.users.find(user => user.id == userid).enabled = enabled; | |||
let user = state.users.find(user => user.id == userid); | |||
user.enabled = enabled; | |||
// increment or not | |||
state.groups.find(group => group.id == 'disabled').usercount += enabled ? -1 : 1; | |||
state.userCount += enabled ? 1 : -1; | |||
console.log(enabled); | |||
user.groups.forEach(group => { | |||
// Increment disabled count | |||
state.groups.find(groupSearch => groupSearch.id == group).disabled += enabled ? -1 : 1; | |||
}); | |||
}, | |||
setUserData(state, { userid, key, value }) { | |||
if (key === 'quota') { |
@@ -238,8 +238,8 @@ export default { | |||
name: 'group', | |||
params: {selectedGroup: group.id} | |||
}; | |||
item.text = group.name; // group name | |||
item.utils = {counter: group.usercount}; // users count | |||
item.text = group.name; // group name | |||
item.utils = {counter: group.usercount - group.disabled}; // users count | |||
if (item.id !== 'admin' && item.id !== 'disabled' && this.settings.isAdmin) { | |||
// add delete button on real groups | |||
@@ -276,14 +276,6 @@ export default { | |||
utils: {counter: this.userCount} | |||
}); | |||
// Set current group as active | |||
let activeGroup = groups.findIndex(group => group.id === this.selectedGroup); | |||
if (activeGroup >= 0) { | |||
groups[activeGroup].classes.push('active'); | |||
} else { | |||
groups[0].classes.push('active'); | |||
} | |||
// Return | |||
return { | |||
id: 'usergrouplist', |