Skip to content

Commit

Permalink
#77 Fixed issues with permissions for users. Added actions on users.
Browse files Browse the repository at this point in the history
Intended permissions are now functional. Just need to add more things to do for the Admin (delete the team, for example).
Remove user function doesn't work either yet, plus there needs to be a leave team option.
Refactored the role definitions and put them in keystoneguru.php.
  • Loading branch information
Wotuu committed Apr 18, 2019
1 parent 1a9eed7 commit 234797d
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 86 deletions.
41 changes: 24 additions & 17 deletions app/Models/Team.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@
*/
class Team extends IconFileModel
{
/**
* @var array List of current roles for a user in a team.
*/
private static $_roles = ['member' => 1, 'collaborator' => 2, 'moderator' => 3, 'admin' => 4];

/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
Expand Down Expand Up @@ -63,20 +59,29 @@ public function getUserRole($user)

/**
* Get the roles that a user may assign to other users in this team.
* @param $user User
* @param $user User The user attempting to change roles.
* @param $targetUser User The user that is targeted for a role change.
* @return array
*/
public function getAssignableRoles($user)
public function getAssignableRoles($user, $targetUser)
{
$userRole = $this->getUserRole($user);
$targetUserRole = $this->getUserRole($targetUser);
$result = [];

if ($userRole !== false) {
// Count down from all roles that exist, starting by the role the user currently has
$userRoleKey = self::$_roles[$userRole];
for ($i = $userRoleKey; $i > 0; $i--) {
// array_search to find key by value
$result[] = array_search($i, self::$_roles);
// If both users have a valid role (should always be the case)
if ($userRole !== false && $targetUserRole !== false) {
$roles = config('keystoneguru.team_roles');
$userRoleKey = $roles[$userRole];
$targetUserRoleKey = $roles[$targetUserRole];
// If the current user is a moderator or admin, and (if user is admin or the current user outranks the other user)
if ($userRoleKey >= 3 && ($userRoleKey === 4 || $userRoleKey > $targetUserRoleKey)) {

// Count down from all roles that exist, starting by the role the user currently has
for ($i = $userRoleKey; $i > 0; $i--) {
// array_search to find key by value
$result[] = array_search($i, $roles);
}
}
}

Expand All @@ -96,16 +101,17 @@ public function getAssignableRoles($user)
public function canChangeRole($user, $targetUser, $role)
{
$result = false;
$roles = config('keystoneguru.team_roles');

// Only if it's a valid role
if (isset(self::$_roles[$role])) {
if (isset($roles[$role])) {
$userRole = $this->getUserRole($user);
$targetUserRole = $this->getUserRole($targetUser);

if ($userRole !== false && $targetUserRole !== false) {
$userRoleKey = self::$_roles[$userRole];
$targetUserRoleKey = self::$_roles[$targetUserRole];
$targetRoleKey = self::$_roles[$role];
$userRoleKey = $roles[$userRole];
$targetUserRoleKey = $roles[$targetUserRole];
$targetRoleKey = $roles[$role];

// User has a bigger role, and then only up to where the current user is (no promotions past their own
// rank) the person, and only users who are currently a moderator or admin may change roles
Expand All @@ -119,8 +125,9 @@ public function canChangeRole($user, $targetUser, $role)
public function changeRole($user, $role)
{
$teamUser = $this->teamusers()->where('user_id', $user->id)->get()->first();
$roles = config('keystoneguru.team_roles');
// Only when user is part of the team, and when the role is a valid one.
if ($teamUser !== null && isset(self::$_roles[$role])) {
if ($teamUser !== null && isset($roles[$role])) {
// Update the role with the new one
$teamUser->role = $role;
$teamUser->save();
Expand Down
10 changes: 7 additions & 3 deletions app/Models/TeamUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@

namespace App\Models;

use App\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

/**
* @property $id int
* @property $team_id int
* @property $user_id int
* @property $role string
*
* @property Collection $team
* @property Collection $user
* @property Carbon $created_at
* @property Carbon $updated_at
*
* @property Team $team
* @property User $user
*
* @mixin \Eloquent
*/
Expand Down
7 changes: 6 additions & 1 deletion config/keystoneguru.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,10 @@
* The amount of hours it takes before a dungeon route that is created through the 'try' functionality expires and
* is deleted from the server.
*/
'try_dungeon_route_expires_hours' => 24
'try_dungeon_route_expires_hours' => 24,

/**
* @var array List of current roles for a user in a team.
*/
'team_roles' => ['member' => 1, 'collaborator' => 2, 'moderator' => 3, 'admin' => 4]
];
2 changes: 0 additions & 2 deletions resources/assets/js/custom/inline/dungeonroute/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,6 @@ class DungeonrouteTable extends InlineCode {
});
}

console.log(columns);

return columns;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
<select class="form-control selectpicker role_selection" data-username="{{username}}">
{{#roles}}
{{#select role}}
<option value="{{name}}" data-icon="fas {{icon}}">{{label}}</option>
{{/select}}
{{/roles}}
</select>
<button class="btn btn-danger">
<span class="d-xl-none"><i class="fas fa-user-minus"></i></span>
<span class="d-none d-xl-block"><i class="fas fa-user-minus"></i> {{remove_label}}</span>
</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<i class="fas {{icon}}"></i> {{label}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<select class="form-control selectpicker role_selection" data-username="{{username}}">
{{#select role}}
{{#roles}}
<option value="{{name}}" data-icon="fas {{icon}}">{{label}}</option>
{{/roles}}
{{/select}}
</select>
9 changes: 5 additions & 4 deletions resources/lang/en/js.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,9 @@
'admin_label' => 'Own',
'change_role_success' => 'Permissions updated',

'team_admin' => 'Admin',
'team_moderator' => 'Moderator',
'team_collaborator' => 'Collaborator',
'team_member' => 'Member',
'team_admin' => 'Administrate team',
'team_moderator' => 'Moderate team',
'team_collaborator' => 'Edit routes',
'team_member' => 'View routes',
'remove_label' => 'Remove'
];
8 changes: 4 additions & 4 deletions resources/views/common/dungeonroute/table.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@
&nbsp;
</div>
<div class="mb-2 text-right">
<div id="table_biglist_btn"
<button id="table_biglist_btn"
class="btn {{ $cookieViewMode === 'biglist' ? 'btn-primary' : 'btn-default' }} table_list_view_toggle"
data-viewmode="biglist">
<i class="fas fa-th-list"></i>
</div>
<div id="table_list_btn"
</button>
<button id="table_list_btn"
class="btn {{ $cookieViewMode === 'list' ? 'btn-primary' : 'btn-default' }} table_list_view_toggle"
data-viewmode="list">
<i class="fas fa-list"></i>
</div>
</button>
</div>
</div>
</div>
Expand Down
152 changes: 109 additions & 43 deletions resources/views/team/edit.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php
/** @var \App\Models\Team $model */
$title = isset($model) ? __('Edit team') : __('New team');
$userRole = $model->getUserRole(Auth::user());
?>
@extends('layouts.app', ['showAds' => false, 'title' => $title])
@section('header-title', $title)
Expand All @@ -24,66 +26,81 @@
$teamuser->created_at->toDateTimeString(),
$teamuser->role,
// Any and all roles that the user may assign to other users
$model->getAssignableRoles($teamuser->user)
$model->getAssignableRoles(Auth::user(), $teamuser->user)
];
}
?>
var _data = {!! json_encode($data) !!};
var _teamId = {!! $model->id !!};
var _userIsModerator = {!! $userRole === 'admin' || $userRole === 'moderator' ? 'true' : 'false' !!};
$(function () {
$('#team_members_table').DataTable({
'data': _data,
'columnDefs': [{
'targets': 2,
'render': function (data, type, row, meta) {
// Matching roles to icons
let icons = [{
name: 'member',
icon: 'fa-eye',
label: lang.get('messages.team_member')
}, {
name: 'collaborator',
icon: 'fa-edit',
label: lang.get('messages.team_collaborator')
}, {
name: 'moderator',
icon: 'fa-user-cog',
label: lang.get('messages.team_moderator')
}, {
name: 'admin',
icon: 'fa-crown',
label: lang.get('messages.team_admin')
}];
let roles = [];
// Match the valid roles with roles above
for (let roleIndex in row[3]) {
let role = row[3][roleIndex];
for (let roleCandidateIndex in icons) {
let roleCandidate = icons[roleCandidateIndex];
if (role === roleCandidate.name) {
roles.push(roleCandidate);
}
let columns = [{
'targets': 2,
'render': function (data, type, row, meta) {
let roles = [];
// Match the valid roles with roles above
let assignableRoles = row[3];
for (let roleIndex in assignableRoles) {
if (assignableRoles.hasOwnProperty(roleIndex)) {
// Fetch the role..
let assignableRole = assignableRoles[roleIndex];
let icon = _getIcon(assignableRole);
if (icon !== false) {
roles.push(icon);
}
}
}
console.log('roles', roles);
let result = '';
if (roles.length === 0) {
let icon = _getIcon(data);
// Handlebars the entire thing
let template = Handlebars.templates['team_member_table_actions_template'];
let template = Handlebars.templates['team_member_table_permissions_self_template'];
let templateData = $.extend({
icon: icon.icon,
label: icon.label
}, getHandlebarsDefaultVariables());
result = template(templateData);
} else {
// Handlebars the entire thing
let template = Handlebars.templates['team_member_table_permissions_template'];
let templateData = $.extend({
username: row[0],
role: data,
is_admin: data === 'admin',
roles: roles
}, getHandlebarsDefaultVariables());
result = template(templateData);
}
return result;
},
'orderable': false
}];
// Only admins/moderators have the option to remove members from a team
if (_userIsModerator) {
columns.push({
'targets': 3,
'render': function (data, type, row, meta) {
// Handlebars the entire thing
let template = Handlebars.templates['team_member_table_actions_template'];
let templateData = $.extend({}, getHandlebarsDefaultVariables());
return template(templateData);
},
'orderable': false
}]
}
});
}
$('#team_members_table').DataTable({
'data': _data,
'columnDefs': columns
});
// Fix members data table being in a separate tab ignoring width
Expand All @@ -108,6 +125,48 @@
});
});
});
/**
* Gets icon data for a role.
* @param roleName The name of the role you want icon data for.
* @returns {boolean}
* @private
*/
function _getIcon(roleName) {
// Matching roles to icons
let icons = [{
name: 'member',
icon: 'fa-eye',
label: lang.get('messages.team_member')
}, {
name: 'collaborator',
icon: 'fa-edit',
label: lang.get('messages.team_collaborator')
}, {
name: 'moderator',
icon: 'fa-user-cog',
label: lang.get('messages.team_moderator')
}, {
name: 'admin',
icon: 'fa-crown',
label: lang.get('messages.team_admin')
}];
let result = false;
// For each role there exists
for (let roleCandidateIndex in icons) {
let roleCandidate = icons[roleCandidateIndex];
// Match assignable role with candidate
if (roleName === roleCandidate.name) {
// Found what we're looking for, push the result
result = roleCandidate;
break;
}
}
return result;
}
</script>
@endsection
@endisset
Expand Down Expand Up @@ -174,9 +233,16 @@
<table id="team_members_table" class="tablesorter default_table table-striped w-100" width="100%">
<thead>
<tr>
<th width="65%">{{ __('Name') }}</th>
<th width="20%">{{ __('Join date') }}</th>
<th width="15%">{{ __('Permissions') }}</th>
@if($userRole === 'member' || $userRole === 'collaborator')
<th width="65%">{{ __('Name') }}</th>
<th width="20%">{{ __('Join date') }}</th>
<th width="15%">{{ __('Permissions') }}</th>
@else
<th width="50%">{{ __('Name') }}</th>
<th width="20%">{{ __('Join date') }}</th>
<th width="15%">{{ __('Permissions') }}</th>
<th width="15%">{{ __('Actions') }}</th>
@endif
</tr>
</thead>
</table>
Expand Down
Loading

0 comments on commit 234797d

Please sign in to comment.