Skip to content

Commit

Permalink
Merge branch 'pr/1336' into wip
Browse files Browse the repository at this point in the history
  • Loading branch information
bochoven committed May 11, 2020
2 parents 526783d + e8e09a5 commit e11c739
Show file tree
Hide file tree
Showing 12 changed files with 189 additions and 98 deletions.
2 changes: 2 additions & 0 deletions app/config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ function (){
|
*/
'authorization' => [
'archive' => env('AUTHORIZATION_ARCHIVE', ['admin', 'manager', 'archiver']),
'delete_machine' => env('AUTHORIZATION_DELETE_MACHINE', ['admin', 'manager']),
'global' => env('AUTHORIZATION_GLOBAL', ['admin']),
],
Expand All @@ -196,6 +197,7 @@ function (){
'roles' => [
'admin' => env('ROLES_ADMIN', ['*']),
'manager' => env('ROLES_MANAGER', []),
'archiver' => env('ROLES_ARCHIVER', []),
],

/*
Expand Down
54 changes: 54 additions & 0 deletions app/controllers/Archiver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace munkireport\controller;

use \Controller, \View, \Model, \Exception, \Reportdata_model;

class Archiver extends Controller
{
public function __construct()
{
// Check authorization
$this->authorized() || jsonError('Authenticate first', 403);
$this->authorized('archive') || jsonError('You need to be archiver, manager or admin', 403);

// Connect to database
$this->connectDB();
}


//===============================================================

public function index()
{
echo 'Archiver';
}

//===============================================================

public function update_status($serial_number = '')
{
if (! isset($_POST['status'])) {
jsonError('No status found');
}
$changes = Reportdata_model::where('serial_number', $serial_number)
->update(
[
'archive_status' => intval($_POST['status']),
]
);
jsonView(['updated' => intval($_POST['status'])]);
}

public function bulk_update_status()
{
if( ! $days = intval(post('days'))){
jsonError('No days sent');
}
$expire_timestamp = time() - ($days * 24 * 60 * 60);
$changes = Reportdata_model::where('timestamp', '<', $expire_timestamp)
->where('archive_status', 0)
->update(['archive_status' => 1]);
jsonView(['updated' => $changes]);
}
}
26 changes: 0 additions & 26 deletions app/controllers/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,30 +118,4 @@ private function isTableNameOk($name)

return true;
}

public function update_status($serial_number = '')
{
if (! isset($_POST['status'])) {
jsonError('No status found');
}
$changes = Reportdata_model::where('serial_number', $serial_number)
->update(
[
'archive_status' => intval($_POST['status']),
]
);
jsonView(['updated' => intval($_POST['status'])]);
}

public function bulk_update_status()
{
if( ! $days = intval(post('days'))){
jsonError('No days sent');
}
$expire_timestamp = time() - ($days * 24 * 60 * 60);
$changes = Reportdata_model::where('timestamp', '<', $expire_timestamp)
->where('archive_status', 0)
->update(['archive_status' => 1]);
jsonView(['updated' => $changes]);
}
}
54 changes: 54 additions & 0 deletions app/helpers/site_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,60 @@ function assocToArray($array)
return $result;
}

function authorized($what)
{
if (! isset($_SESSION)) {
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_path', conf('subdirectory'));
ini_set('session.cookie_httponly', true);
ini_set('session.cookie_samesite', "Lax");
session_start();
}

// Check if we have a valid user
if (! isset($_SESSION['role'])) {
return false;
}

// Check if POST and check CSRF
if(in_array($_SERVER['REQUEST_METHOD'], ['POST', 'DELETE'])){
verifyCSRF();
}

// Check for a specific authorization item
if ($what) {
foreach (conf('authorization', array()) as $item => $roles) {
if ($what === $item) {
// Check if there is a matching role
if (in_array($_SESSION['role'], $roles)) {
return true;
}

// Role not found: unauthorized!
return false;
}
}
}

// There is no matching rule, you're authorized!
return true;
}

function verifyCSRF()
{
$session_token = sess_get('csrf_token');

$sent_token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';

if( hash_equals($session_token, $sent_token)) return;

// Exit with error page todo: use a json response
jsonView($msg = ['error' => 'CSRF Token Mismatch'], $status_code = 403, $exit = true);
}



/**
* Check if current user may access data for serial number
*
Expand Down
31 changes: 26 additions & 5 deletions app/lib/munkireport/AuthHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ public function setSessionProps($show = false)

// Check if Business Units are enabled in the config file
$bu_enabled = conf('enable_business_units', false);

// Check if user is global admin
if ($_SESSION['auth'] == 'noauth' or $_SESSION['role'] == 'admin') {
unset($_SESSION['business_unit']);
Expand All @@ -166,15 +165,22 @@ public function setSessionProps($show = false)
$_SESSION['business_unit'] = 0;

// Lookup user in business units
$bu = new Business_unit;
if ($bu->retrieveOne("property IN ('manager', 'user') AND value=?", $_SESSION['user'])) {
$bu = Business_unit::whereIn('property', ['manager', 'archiver', 'user'])
->where('value', $_SESSION['user'])
->first();

if ($bu) {
$_SESSION['role'] = $bu->property; // manager, user
$_SESSION['role_why'] = $_SESSION['user'].' found in Business Unit '. $bu->unitid;
$_SESSION['business_unit'] = $bu->unitid;
} else {
// Lookup groups in Business Units
foreach ($_SESSION['groups'] as $group) {
if ($bu->retrieveOne("property IN ('manager', 'user') AND value=?", '@' . $group)) {
$bu = Business_unit::whereIn('property', ['manager', 'archiver', 'user'])
->where('value', '@' . $group)
->first();

if ($bu) {
$_SESSION['role'] = $bu->property; // manager, user
$_SESSION['role_why'] = 'Group "'. $group . '" found in Business Unit '. $bu->unitid;
$_SESSION['business_unit'] = $bu->unitid;
Expand All @@ -199,7 +205,22 @@ public function setSessionProps($show = false)
$_SESSION['machine_groups'] = array_unique(array_merge($machine_groups, $mg->get_group_ids()));
} else {
// Only get machine_groups for business unit
$_SESSION['machine_groups'] = $bu->get_machine_groups($bu->unitid);
// $_SESSION['machine_groups'] = $bu->get_machine_groups($bu->unitid);
$_SESSION['machine_groups'] = Business_unit::where('unitid', $bu->unitid)
->where('property', 'machine_group')
->get()
->pluck('value')
->toArray();

// public function get_machine_groups($id)
// {
// $out = array();
// foreach ($this->retrieveMany('unitid=? AND property=?', array($id, 'machine_group')) as $obj) {
// $out[] = intval($obj->value);
// }
// return $out;
// }

}
$_SESSION['initialized'] = true;
} catch (\Exception $e) {
Expand Down
9 changes: 7 additions & 2 deletions app/lib/munkireport/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@ public function isManager()
return $this->_getRole() == 'manager';
}

public function isArchiver()
{
return $this->_getRole() == 'archiver';
}

public function canArchive()
{
return $this->isAdmin() || $this->isManager();
return $this->isAdmin() || $this->isManager() || $this->isArchiver();
}

public function canAccessMachineGroup($id)
Expand All @@ -51,4 +56,4 @@ private function _getRole()
{
return $this->session['role'] ?? 'nobody';
}
}
}
32 changes: 28 additions & 4 deletions app/views/admin/business_units.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
var edit = function(){

var fields = {name:'', 'address':'', link: ''},
dataTemplate = {unitid:'new', users:['#'], managers:['#'], machine_groups:['#'], iteminfo:[]};
dataTemplate = {unitid:'new', users:['#'], archivers:['#'], managers:['#'], machine_groups:['#'], iteminfo:[]};

// Clone unit data
var data = $.extend(true, {}, $(this).closest('.unit').data() || dataTemplate);
Expand Down Expand Up @@ -556,6 +556,9 @@
if( ! data.managers.length){
data.managers = ['#'];
}
if( ! data.archivers.length){
data.archivers = ['#'];
}
if( ! data.users.length){
data.users = ['#'];
}
Expand Down Expand Up @@ -690,6 +693,7 @@
groupname = '',
users = ''
managers = '',
archivers = '',
link = '';

if(data.users)
Expand All @@ -702,6 +706,17 @@
.text(val))
});

}
if(data.archivers)
{
archivers = $('<ul>')
.addClass('list-group');
$.each(data.archivers, function(index, val){
archivers.append($('<li>')
.addClass('list-group-item')
.text(val))
});

}
if(data.managers)
{
Expand Down Expand Up @@ -747,7 +762,7 @@
.addClass('col-lg-12')
.append(link))
.append($('<div>')
.addClass('col-md-4')
.addClass('col-md-3')
.append($('<h4>')
.text('Machine Groups ')
.addClass('alert alert-info')
Expand All @@ -756,7 +771,7 @@
.append($('<div>')
.addClass('list-group machine-groups')))
.append($('<div>')
.addClass('col-md-4')
.addClass('col-md-3')
.append($('<h4>')
.text('Managers ')
.addClass('alert alert-info')
Expand All @@ -765,7 +780,16 @@
.click(editUsers)))
.append(managers))
.append($('<div>')
.addClass('col-md-4')
.addClass('col-md-3')
.append($('<h4>')
.text('Archivers ')
.addClass('alert alert-info')
.append(editButton.clone()
.attr('data-type', 'archivers')
.click(editUsers)))
.append(archivers))
.append($('<div>')
.addClass('col-md-3')
.append($('<h4>')
.text('Users ')
.addClass('alert alert-info')
Expand Down
2 changes: 1 addition & 1 deletion app/views/client/client_detail.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@

<input type="text" class="form-control mr-computer_name_input" readonly>

<?php if($_SESSION['role'] == 'admin'): ?>
<?php if(authorized('archive')): ?>
<div class="input-group-btn">
<button type="button" id="archive_button" class="btn btn-default">
<span class="hidden-sm hidden-xs"></span>
Expand Down
1 change: 1 addition & 0 deletions app/views/partials/head.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
businessUnitsEnabled = <?php echo conf('enable_business_units') ? 'true' : 'false'; ?>;
isAdmin = <?php echo $_SESSION['role'] == 'admin' ? 'true' : 'false'; ?>;
isManager = <?php echo $_SESSION['role'] == 'manager' ? 'true' : 'false'; ?>;
isArchiver = <?php echo $_SESSION['role'] == 'archiver' ? 'true' : 'false'; ?>;
</script>

<script src="<?php echo conf('subdirectory'); ?>assets/js/jquery.js"></script>
Expand Down
25 changes: 14 additions & 11 deletions docs/authorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ At the moment there are 4 roles defined:

* Admin
* Manager
* Archiver
* User
* Nobody

Expand All @@ -13,24 +14,26 @@ At the moment there are 4 roles defined:
When Business Units are **not** configured, the following authorizations apply.
A user that does not have an admin-role or manager-role gets the role of **user**.

Role | View | Delete Machine
------- | ------------ | --------------
admin | All machines | Yes
manager | All machines | Yes
user | All machines | No
Role | View | Delete Machine | Archive Machine
------- | ------------ | -------------- | --------------
admin | All machines | Yes | Yes
manager | All machines | Yes | Yes
archiver| All machines | No | Yes
user | All machines | No | No


## Business Units

When Business Units are enabled, the roles change a little bit.
A user that does not have an admin role and is not found an a business unit gets the role of **nobody**.

Role | View | Delete Machine | Edit Business Units
------- | ------------ | -------------- | -------------------
admin | All machines | Yes | Yes
manager | BU only | BU only | No
user | BU only | No | No
nobody | No machines | No | No
Role | View | Delete Machine | Archive Machine | Edit Business Units
------- | ------------ | -------------- | -------------- | -------------------
admin | All machines | Yes | Yes | Yes
manager | BU only | BU only | Yes | No
archiver| BU only | No | Yes | No
user | BU only | No | No | No
nobody | No machines | No | No | No


## Add role to a user
Expand Down
2 changes: 1 addition & 1 deletion public/assets/js/clients/client_detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ $(document).on('appReady', function(e, lang) {
.click(function(){
var status = $('#archive_button').data('status') == 1 ? 0 : 1;
var settings = { status: status}
$.post(appUrl + '/manager/update_status/' + serialNumber, settings, function(){
$.post(appUrl + '/archiver/update_status/' + serialNumber, settings, function(){
// Change button text
setArchiveStatus(status);
// store new status
Expand Down
Loading

0 comments on commit e11c739

Please sign in to comment.