Skip to content

Commit

Permalink
Merge pull request #12 from simmstein/develop
Browse files Browse the repository at this point in the history
Add additional security and permission settings (thanks @simmstein)
  • Loading branch information
e-alfred authored Dec 28, 2020
2 parents 6aff740 + 1ac5310 commit 9464d62
Show file tree
Hide file tree
Showing 11 changed files with 402 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/vendor
4 changes: 4 additions & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@
<dependencies>
<nextcloud min-version="20" max-version="20" />
</dependencies>
<settings>
<admin>OCA\Printer\Settings\Admin\AllowedGroups</admin>
<admin-section>OCA\Printer\Settings\Admin\Section</admin-section>
</settings>
</info>
3 changes: 3 additions & 0 deletions css/admin.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#printer_admin input {
vertical-align: middle;
}
1 change: 1 addition & 0 deletions img/app-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions js/admin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
let elements = []

const selector = '#printer-message';

const appConfig = (name, value, callbacks) => {
OCP.AppConfig.setValue('printer', name, value, callbacks)
}

const saveSettings = (key) => {
const element = elements.get(key)
let value
let name

if (jQuery(element).is('[data-checkbox]')) {
name = jQuery(element).attr('data-name')
const inputs = jQuery('input[name="' + name + '[]"]:checked')
value = []

inputs.each((i, v) => {
value.push(v.value)
})

value = JSON.stringify(value)
} else {
name = jQuery(element).attr('name')
value = jQuery(element).val()
}

const size = elements.length

if (name === 'cache') {
++value
}

const callbacks = {
success: () => {
OC.msg.finishedSuccess(
selector,
t('printer', (key + 1) + '/' + size)
)

if (key < size - 1) {
saveSettings(++key)
} else {
OC.msg.finishedSuccess(selector, t('printer', 'Saved'))
}
},
error: () => {
OC.msg.finishedError(selector, t('printer', 'Error while saving "' + element + '"'))
}
}

appConfig(name, value, callbacks)
}

jQuery(document).ready(() => {
elements = jQuery('.printer-setting')

jQuery('#printer-save').on('click', (event) => {
event.preventDefault()
OC.msg.startSaving(selector)

saveSettings(0)
});
});
64 changes: 64 additions & 0 deletions lib/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace OCA\Printer;

use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUser;
use OCP\Security\ISecureRandom;

class Config
{
/**
* @var IConfig
*/
protected $config;

/**
* @var ITimeFactory
*/
protected $timeFactory;

/**
* @var IGroupManager
*/
private $groupManager;

/**
* @var ISecureRandom
*/
private $secureRandom;

public function __construct(IConfig $config, IGroupManager $groupManager)
{
$this->config = $config;
$this->groupManager = $groupManager;
}

/**
* @return string[]
*/
public function getAllowedGroupIds(): array
{
$groups = $this->config->getAppValue('printer', 'allowed_groups', '[]');
$groups = json_decode($groups, true);

return \is_array($groups) ? $groups : [];
}

public function isDisabledForUser(IUser $user): bool
{
$allowedGroups = $this->getAllowedGroupIds();

if (empty($allowedGroups)) {
return false;
}

$userGroups = $this->groupManager->getUserGroupIds($user);

return empty(array_intersect($allowedGroups, $userGroups));
}
}
122 changes: 71 additions & 51 deletions lib/Controller/PrinterController.php
Original file line number Diff line number Diff line change
@@ -1,59 +1,79 @@
<?php

namespace OCA\Printer\Controller;

use OCA\Printer\Config;
use OCA\Printer\Service\Printer;
use OCP\AppFramework\Controller;
use OCP\IRequest;
use OC\Files\Filesystem;
use OCP\AppFramework\Http\JSONResponse;
use OCP\IRequest;
use OCP\IUserSession;
use Symfony\Component\Process\Exception\ProcessFailedException;

class PrinterController extends Controller
{
/**
* @var OC\L10N\LazyL10N
*/
protected $language;

/**
* @var Printer
*/
protected $printer;

/**
* @var Config
*/
protected $config;

public function __construct(string $appName, IRequest $request, Printer $printer, Config $config)
{
parent::__construct($appName, $request);

$this->language = \OC::$server->getL10N('printer');
$this->printer = $printer;
$this->config = $config;
}

/**
* @NoAdminRequired
*/
public function printfile(string $sourcefile, string $orientation): JSONResponse
{
$file = \OC\Files\Filesystem::getLocalFile($sourcefile);

$success = [
'response' => 'success',
'msg' => $this->language->t('Print succeeded!'),
];

$error = [
'response' => 'error',
'msg' => $this->language->t('Print failed'),
];

$notAllowed = [
'response' => 'error',
'msg' => $this->language->t('User not allowed'),
];

$user = \OC::$server[IUserSession::class]->getUser();

if (!$user || $this->config->isDisabledForUser($user)) {
return new JSONResponse($notAllowed);
}

if (!$this->printer->isValidOrientation($orientation)) {
return new JSONResponse($error);
}

try {
$this->printer->print($file, $orientation);

class PrinterController extends Controller {

protected $language;

public function __construct($appName, IRequest $request) {

parent::__construct($appName, $request);

// get i10n
$this->language = \OC::$server->getL10N('printer');

}

/**
* callback function to get md5 hash of a file
* @NoAdminRequired
* @param (string) $sourcefile - filename
* @param (string) $orientation - Orientation of printed file
*/
public function printfile($sourcefile, $orientation) {
if($orientation === "landscape") {
$filefullpath = \OC\Files\Filesystem::getLocalFile($sourcefile);
exec('lpr "' . $filefullpath . '"');
return new JSONResponse(
array(
'response' => 'success',
'msg' => $this->language->t('Print succeeded!')
)
);
}

if($orientation === "portrait"){
$filefullpath = \OC\Files\Filesystem::getLocalFile($sourcefile);
exec('lpr -o orientation-requested=4 "' . $filefullpath . '"');
return new JSONResponse(
array(
'response' => 'success',
'msg' => $this->language->t('Print succeeded!')
)
);
} else {
return new JSONResponse(
array(
'response' => 'error',
'msg' => $this->language->t('Print failed')
)
);
};
}
return new JSONResponse($success);
} catch (ProcessFailedException $exception) {
return new JSONResponse($error);
}
}
}
44 changes: 44 additions & 0 deletions lib/Service/Printer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Service;
namespace OCA\Printer\Service;

use Symfony\Component\Process\Process;

/**
* class Printer.
*
* @author Simon Vieille <[email protected]>
*/
class Printer
{
public function print(string $file, string $orientation)
{
$options = [
'landscape' => [
'lpr',
$file,
],
'portrait' => [
'lpr',
'-o',
'orientation-requested=4',
$file,
],
];

$process = new Process($options[$orientation]);
$process->mustRun();
}

/**
* Validates an orientation.
*/
public function isValidOrientation(string $orientation): bool
{
return in_array($orientation, [
'landscape',
'portrait',
]);
}
}
63 changes: 63 additions & 0 deletions lib/Settings/Admin/AllowedGroups.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace OCA\Printer\Settings\Admin;

use OCA\Printer\Config;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IGroupManager;
use OCP\IInitialStateService;
use OCP\Settings\ISettings;

class AllowedGroups implements ISettings
{
/**
* @var Config
*/
private $config;

/**
* @var IInitialStateService
*/
private $initialStateService;

/**
* @var IGroupManager
*/
private $groupManager;

public function __construct(Config $config, IInitialStateService $initialStateService, IGroupManager $groupManager)
{
$this->config = $config;
$this->initialStateService = $initialStateService;
$this->groupManager = $groupManager;
}

public function getForm(): TemplateResponse
{
$this->initialStateService->provideInitialState(
'printer',
'allowed_groups',
$this->config->getAllowedGroupIds()
);

$groups = $this->groupManager->search('', 100);
$allowedGroups = $this->config->getAllowedGroupIds();

return new TemplateResponse('printer', 'settings/admin/allowed-groups', [
'groups' => $groups,
'allowedGroups' => $allowedGroups,
], '');
}

public function getSection(): string
{
return 'printer';
}

public function getPriority(): int
{
return 10;
}
}
Loading

0 comments on commit 9464d62

Please sign in to comment.