mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-22 09:53:35 +02:00
Added permissions to label system.
This commit is contained in:
parent
fde1d7be4f
commit
5a9be023b1
6 changed files with 62 additions and 27 deletions
|
@ -466,11 +466,22 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
|
||||||
edit_options:
|
edit_options:
|
||||||
label: "perm.self.edit_options"
|
label: "perm.self.edit_options"
|
||||||
bit: 2
|
bit: 2
|
||||||
delete_profiles:
|
alsoSet: ['create_labels']
|
||||||
label: "perm.self.delete_profiles"
|
read_profiles:
|
||||||
bit: 4
|
label: "perm.self.read_profiles"
|
||||||
|
bit: 10
|
||||||
edit_profiles:
|
edit_profiles:
|
||||||
label: "perm.self.edit_profiles"
|
label: "perm.self.edit_profiles"
|
||||||
bit: 6
|
bit: 6
|
||||||
|
alsoSet: ['read_profiles']
|
||||||
|
create_profiles:
|
||||||
|
label: "perm.self.create_profiles"
|
||||||
|
bit: 8
|
||||||
|
alsoSet: ['read_profiles', 'edit_profiles']
|
||||||
|
delete_profiles:
|
||||||
|
label: "perm.self.delete_profiles"
|
||||||
|
bit: 4
|
||||||
|
alsoSet: ['read_profiles', 'edit_profiles', 'create_profiles']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -61,25 +61,19 @@ class LabelController extends AbstractController
|
||||||
$this->rangeParser = $rangeParser;
|
$this->rangeParser = $rangeParser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/{profile}/{part}/view")
|
|
||||||
*/
|
|
||||||
public function view(LabelProfile $profile, Part $part)
|
|
||||||
{
|
|
||||||
$label = $this->labelGenerator->generateLabel($profile->getOptions(), $part);
|
|
||||||
|
|
||||||
$response = new LabelResponse($label);
|
|
||||||
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE, 'label.pdf');
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/dialog", name="label_dialog")
|
* @Route("/dialog", name="label_dialog")
|
||||||
* @Route("/{profile}/dialog", name="label_dialog_profile")
|
* @Route("/{profile}/dialog", name="label_dialog_profile")
|
||||||
*/
|
*/
|
||||||
public function generator(Request $request, ?LabelProfile $profile = null)
|
public function generator(Request $request, ?LabelProfile $profile = null)
|
||||||
{
|
{
|
||||||
|
$this->denyAccessUnlessGranted('@labels.create_labels');
|
||||||
|
|
||||||
|
//If we inherit a LabelProfile, the user need to have access to it...
|
||||||
|
if ($profile !== null) {
|
||||||
|
$this->denyAccessUnlessGranted('read', $profile);
|
||||||
|
}
|
||||||
|
|
||||||
if ($profile) {
|
if ($profile) {
|
||||||
$label_options = $profile->getOptions();
|
$label_options = $profile->getOptions();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -29,9 +29,17 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
class LabelDialogType extends AbstractType
|
class LabelDialogType extends AbstractType
|
||||||
{
|
{
|
||||||
|
protected $security;
|
||||||
|
|
||||||
|
public function __construct(Security $security)
|
||||||
|
{
|
||||||
|
$this->security = $security;
|
||||||
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
$builder->add('target_id', TextType::class, [
|
$builder->add('target_id', TextType::class, [
|
||||||
|
@ -45,6 +53,8 @@ class LabelDialogType extends AbstractType
|
||||||
|
|
||||||
$builder->add('options', LabelOptionsType::class, [
|
$builder->add('options', LabelOptionsType::class, [
|
||||||
'label' => false,
|
'label' => false,
|
||||||
|
'disabled' => !$this->security->isGranted('@labels.edit_options'),
|
||||||
|
|
||||||
]);
|
]);
|
||||||
$builder->add('update', SubmitType::class, [
|
$builder->add('update', SubmitType::class, [
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,19 @@ use App\Entity\UserSystem\User;
|
||||||
class LabelProfileVoter extends ExtendedVoter
|
class LabelProfileVoter extends ExtendedVoter
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protected const MAPPING = [
|
||||||
|
'read' => 'read_profiles',
|
||||||
|
'create' => 'create_profiles',
|
||||||
|
'edit' => 'edit_profiles',
|
||||||
|
'delete' => 'delete_profiles',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
protected function voteOnUser($attribute, $subject, User $user): bool
|
protected function voteOnUser($attribute, $subject, User $user): bool
|
||||||
{
|
{
|
||||||
return true;
|
return $this->resolver->inherit($user, 'labels', self::MAPPING[$attribute]) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +48,11 @@ class LabelProfileVoter extends ExtendedVoter
|
||||||
protected function supports($attribute, $subject)
|
protected function supports($attribute, $subject)
|
||||||
{
|
{
|
||||||
if ($subject instanceof LabelProfile) {
|
if ($subject instanceof LabelProfile) {
|
||||||
return true;
|
if (!isset(self::MAPPING[$attribute])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->resolver->isValidOperation('labels', self::MAPPING[$attribute]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -118,10 +118,12 @@ class ToolsTreeBuilder
|
||||||
{
|
{
|
||||||
$nodes = [];
|
$nodes = [];
|
||||||
|
|
||||||
$nodes[] = new TreeViewNode(
|
if($this->security->isGranted('@labels.create_labels')) {
|
||||||
$this->translator->trans('tree.tools.tools.label_dialog'),
|
$nodes[] = new TreeViewNode(
|
||||||
$this->urlGenerator->generate('label_dialog')
|
$this->translator->trans('tree.tools.tools.label_dialog'),
|
||||||
);
|
$this->urlGenerator->generate('label_dialog')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
$nodes[] = new TreeViewNode(
|
$nodes[] = new TreeViewNode(
|
||||||
$this->translator->trans('tree.tools.tools.label_scanner'),
|
$this->translator->trans('tree.tools.tools.label_scanner'),
|
||||||
|
@ -194,7 +196,7 @@ class ToolsTreeBuilder
|
||||||
$this->urlGenerator->generate('measurement_unit_new')
|
$this->urlGenerator->generate('measurement_unit_new')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ($this->security->isGranted('create', new LabelProfile())) {
|
if ($this->security->isGranted('read', new LabelProfile())) {
|
||||||
$nodes[] = new TreeViewNode(
|
$nodes[] = new TreeViewNode(
|
||||||
$this->translator->trans('tree.tools.edit.label_profile'),
|
$this->translator->trans('tree.tools.edit.label_profile'),
|
||||||
$this->urlGenerator->generate('label_profile_new')
|
$this->urlGenerator->generate('label_profile_new')
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
{% macro profile_dropdown(type, id = null, include_text = true, btn_type = 'btn-secondary') %}
|
{% macro profile_dropdown(type, id = null, include_text = true, btn_type = 'btn-secondary') %}
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn {{ btn_type }} dropdown-toggle" title="{% trans %}label_generator.label_btn{% endtrans %}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button type="button" class="btn {{ btn_type }} dropdown-toggle" title="{% trans %}label_generator.label_btn{% endtrans %}"
|
||||||
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" {% if not is_granted("@labels.create_labels") %}disabled{% endif %}>
|
||||||
<i class="fas fa-fw fa-qrcode"></i> {% if include_text %}{% trans %}label_generator.label_btn{% endtrans %}{% endif %}
|
<i class="fas fa-fw fa-qrcode"></i> {% if include_text %}{% trans %}label_generator.label_btn{% endtrans %}{% endif %}
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
{% set profiles = label_profile_dropdown_helper.dropdownProfiles(type) %}
|
{% if is_granted('@labels.read_profiles') %}
|
||||||
|
{% set profiles = label_profile_dropdown_helper.dropdownProfiles(type) %}
|
||||||
|
{% else %}
|
||||||
|
{% set profiles = [] %}
|
||||||
|
{% endif %}
|
||||||
{% for profile in profiles %}
|
{% for profile in profiles %}
|
||||||
<a class="dropdown-item" href="{{ path('label_dialog_profile', {'profile': profile.id, 'target_type': type, 'target_id': id, 'generate': true}) }}">{{ profile.name }}</a>
|
<a class="dropdown-item" href="{{ path('label_dialog_profile', {'profile': profile.id, 'target_type': type, 'target_id': id, 'generate': true}) }}">{{ profile.name }}</a>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if profiles is not empty %}
|
{% if profiles is not empty and is_granted('@labels.edit_options') %}
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="dropdown-item" href="{{ path('label_dialog', {'target_type': type, 'target_id': id}) }}">{% trans %}label_generator.label_empty{% endtrans %}</a>
|
{% if is_granted('@labels.edit_options') %} {# An empty dialog does not make much sense, when you can not edit the options... #}
|
||||||
|
<a class="dropdown-item" href="{{ path('label_dialog', {'target_type': type, 'target_id': id}) }}">{% trans %}label_generator.label_empty{% endtrans %}</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
Loading…
Add table
Add a link
Reference in a new issue