Added permissions to control access to API and manage API tokens

This commit is contained in:
Jan Böhmer 2023-08-26 22:57:50 +02:00
parent be14fe548c
commit 8fe3f4cf5c
7 changed files with 60 additions and 26 deletions

View file

@ -69,3 +69,5 @@ security:
# We get into trouble with the U2F authentication, if the calls to the trees trigger an 2FA login # We get into trouble with the U2F authentication, if the calls to the trees trigger an 2FA login
# This settings should not do much harm, because a read only access to show available data structures is not really critical # This settings should not do much harm, because a read only access to show available data structures is not really critical
- { path: "^/\\w{2}/tree", role: PUBLIC_ACCESS } - { path: "^/\\w{2}/tree", role: PUBLIC_ACCESS }
# Restrict access to API to users, which has the API access permission
- { path: "^/api", allow_if: 'is_granted("@api.access_api") and is_authenticated()' }

View file

@ -254,6 +254,7 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
show_updates: show_updates:
label: "perm.system.show_available_updates" label: "perm.system.show_available_updates"
attachments: attachments:
label: "perm.part.attachments" label: "perm.part.attachments"
operations: operations:
@ -304,4 +305,11 @@ perms: # Here comes a list with all Permission names (they have a perm_[name] co
label: "perm.revert_elements" label: "perm.revert_elements"
alsoSet: ['read_profiles', 'edit_profiles', 'create_profiles', 'delete_profiles'] alsoSet: ['read_profiles', 'edit_profiles', 'create_profiles', 'delete_profiles']
api:
label: "perm.api"
operations:
access_api:
label: "perm.api.access_api"
manage_tokens:
label: "perm.api.manage_tokens"
alsoSet: ['access_api']

View file

@ -406,6 +406,8 @@ class UserSettingsController extends AbstractController
#[Route('/api_token/create', name: 'user_api_token_create')] #[Route('/api_token/create', name: 'user_api_token_create')]
public function addApiToken(Request $request, EntityManagerInterface $entityManager): Response public function addApiToken(Request $request, EntityManagerInterface $entityManager): Response
{ {
$this->denyAccessUnlessGranted('@api.manage_tokens');
$token = new ApiToken(); $token = new ApiToken();
$token->setUser($this->getUser()); $token->setUser($this->getUser());

View file

@ -102,7 +102,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe
final public const ID_ANONYMOUS = 1; final public const ID_ANONYMOUS = 1;
#[Groups(['user:read'])] #[Groups(['user:read'])]
protected ?int $id; protected ?int $id = null;
#[Groups(['user:read'])] #[Groups(['user:read'])]
protected ?\DateTimeInterface $lastModified = null; protected ?\DateTimeInterface $lastModified = null;

View file

@ -55,7 +55,9 @@
</table> </table>
{% endif %} {% endif %}
<a href="{{ path('user_api_token_create') }}" class="btn btn-success" ><i class="fas fa-plus-square fa-fw"></i> {% trans %}api_token.create_new{% endtrans %}</a> <a href="{{ path('user_api_token_create') }}" class="btn btn-success" {% if not is_granted('@api.manage_tokens') %}disabled="disabled"{% endif %}>
<i class="fas fa-plus-square fa-fw"></i> {% trans %}api_token.create_new{% endtrans %}
</a>
</div> </div>
</div> </div>

View file

@ -77,5 +77,7 @@
</div> </div>
</div> </div>
{% if is_granted("@api.access_api") %}
{% include "users/_api_tokens.html.twig" %} {% include "users/_api_tokens.html.twig" %}
{% endif %}
{% endblock %} {% endblock %}

View file

@ -731,10 +731,10 @@
</notes> </notes>
<segment> <segment>
<source>user.edit.tfa.disable_tfa_message</source> <source>user.edit.tfa.disable_tfa_message</source>
<target>This will disable &lt;b&gt;all active two-factor authentication methods of the user&lt;/b&gt; and delete the &lt;b&gt;backup codes&lt;/b&gt;! <target><![CDATA[This will disable <b>all active two-factor authentication methods of the user</b> and delete the <b>backup codes</b>!
&lt;br&gt; <br>
The user will have to set up all two-factor authentication methods again and print new backup codes! &lt;br&gt;&lt;br&gt; The user will have to set up all two-factor authentication methods again and print new backup codes! <br><br>
&lt;b&gt;Only do this if you are absolutely sure about the identity of the user (seeking help), otherwise the account could be compromised by an attacker!&lt;/b&gt;</target> <b>Only do this if you are absolutely sure about the identity of the user (seeking help), otherwise the account could be compromised by an attacker!</b>]]></target>
</segment> </segment>
</unit> </unit>
<unit id="02HvwiS" name="user.edit.tfa.disable_tfa.btn"> <unit id="02HvwiS" name="user.edit.tfa.disable_tfa.btn">
@ -11326,67 +11326,67 @@ Element 3</target>
</segment> </segment>
</unit> </unit>
<unit id="DGczoY6" name="tfa_u2f.add_key.registration_error"> <unit id="DGczoY6" name="tfa_u2f.add_key.registration_error">
<segment state="translated"> <segment>
<source>tfa_u2f.add_key.registration_error</source> <source>tfa_u2f.add_key.registration_error</source>
<target>An error occurred during the registration of the security key. Try again or use another security key!</target> <target>An error occurred during the registration of the security key. Try again or use another security key!</target>
</segment> </segment>
</unit> </unit>
<unit id="ie0Ca0l" name="log.target_type.none"> <unit id="ie0Ca0l" name="log.target_type.none">
<segment state="translated"> <segment>
<source>log.target_type.none</source> <source>log.target_type.none</source>
<target>None</target> <target>None</target>
</segment> </segment>
</unit> </unit>
<unit id="R2nX4ip" name="ui.darkmode.light"> <unit id="R2nX4ip" name="ui.darkmode.light">
<segment state="translated"> <segment>
<source>ui.darkmode.light</source> <source>ui.darkmode.light</source>
<target>Light</target> <target>Light</target>
</segment> </segment>
</unit> </unit>
<unit id="3NHpuW3" name="ui.darkmode.dark"> <unit id="3NHpuW3" name="ui.darkmode.dark">
<segment state="translated"> <segment>
<source>ui.darkmode.dark</source> <source>ui.darkmode.dark</source>
<target>Dark</target> <target>Dark</target>
</segment> </segment>
</unit> </unit>
<unit id="4TGOK5_" name="ui.darkmode.auto"> <unit id="4TGOK5_" name="ui.darkmode.auto">
<segment state="translated"> <segment>
<source>ui.darkmode.auto</source> <source>ui.darkmode.auto</source>
<target>Auto (decide based on system settings)</target> <target>Auto (decide based on system settings)</target>
</segment> </segment>
</unit> </unit>
<unit id="9N0N8aL" name="label_generator.no_lines_given"> <unit id="9N0N8aL" name="label_generator.no_lines_given">
<segment state="translated"> <segment>
<source>label_generator.no_lines_given</source> <source>label_generator.no_lines_given</source>
<target>No text content given! The labels will remain empty.</target> <target>No text content given! The labels will remain empty.</target>
</segment> </segment>
</unit> </unit>
<unit id="RdFvZsb" name="user.password_strength.very_weak"> <unit id="RdFvZsb" name="user.password_strength.very_weak">
<segment state="translated"> <segment>
<source>user.password_strength.very_weak</source> <source>user.password_strength.very_weak</source>
<target>Very weak</target> <target>Very weak</target>
</segment> </segment>
</unit> </unit>
<unit id="IBjmblZ" name="user.password_strength.weak"> <unit id="IBjmblZ" name="user.password_strength.weak">
<segment state="translated"> <segment>
<source>user.password_strength.weak</source> <source>user.password_strength.weak</source>
<target>Weak</target> <target>Weak</target>
</segment> </segment>
</unit> </unit>
<unit id="qSm_ID0" name="user.password_strength.medium"> <unit id="qSm_ID0" name="user.password_strength.medium">
<segment state="translated"> <segment>
<source>user.password_strength.medium</source> <source>user.password_strength.medium</source>
<target>Medium</target> <target>Medium</target>
</segment> </segment>
</unit> </unit>
<unit id="aWAaADS" name="user.password_strength.strong"> <unit id="aWAaADS" name="user.password_strength.strong">
<segment state="translated"> <segment>
<source>user.password_strength.strong</source> <source>user.password_strength.strong</source>
<target>Strong</target> <target>Strong</target>
</segment> </segment>
</unit> </unit>
<unit id="Wa9CStW" name="user.password_strength.very_strong"> <unit id="Wa9CStW" name="user.password_strength.very_strong">
<segment state="translated"> <segment>
<source>user.password_strength.very_strong</source> <source>user.password_strength.very_strong</source>
<target>Very strong</target> <target>Very strong</target>
</segment> </segment>
@ -11580,25 +11580,25 @@ Please note, that you can not impersonate a disabled user. If you try you will g
</segment> </segment>
</unit> </unit>
<unit id="21tIbM2" name="update_manager.new_version_available.title"> <unit id="21tIbM2" name="update_manager.new_version_available.title">
<segment state="translated"> <segment>
<source>update_manager.new_version_available.title</source> <source>update_manager.new_version_available.title</source>
<target>New version available</target> <target>New version available</target>
</segment> </segment>
</unit> </unit>
<unit id=".c.eoDV" name="update_manager.new_version_available.text"> <unit id=".c.eoDV" name="update_manager.new_version_available.text">
<segment state="translated"> <segment>
<source>update_manager.new_version_available.text</source> <source>update_manager.new_version_available.text</source>
<target>A new version of Part-DB is available. Check it out here</target> <target>A new version of Part-DB is available. Check it out here</target>
</segment> </segment>
</unit> </unit>
<unit id="KOFGqJw" name="update_manager.new_version_available.only_administrators_can_see"> <unit id="KOFGqJw" name="update_manager.new_version_available.only_administrators_can_see">
<segment state="translated"> <segment>
<source>update_manager.new_version_available.only_administrators_can_see</source> <source>update_manager.new_version_available.only_administrators_can_see</source>
<target>Only administrators can see this message.</target> <target>Only administrators can see this message.</target>
</segment> </segment>
</unit> </unit>
<unit id="IFkvJpC" name="perm.system.show_available_updates"> <unit id="IFkvJpC" name="perm.system.show_available_updates">
<segment state="translated"> <segment>
<source>perm.system.show_available_updates</source> <source>perm.system.show_available_updates</source>
<target>Show available Part-DB updates</target> <target>Show available Part-DB updates</target>
</segment> </segment>
@ -11730,22 +11730,40 @@ Please note, that you can not impersonate a disabled user. If you try you will g
</segment> </segment>
</unit> </unit>
<unit id="VVpmfIj" name="project.build.dont_check_quantity"> <unit id="VVpmfIj" name="project.build.dont_check_quantity">
<segment state="translated"> <segment>
<source>project.build.dont_check_quantity</source> <source>project.build.dont_check_quantity</source>
<target>Do not check quantities</target> <target>Do not check quantities</target>
</segment> </segment>
</unit> </unit>
<unit id="AzYSIiX" name="project.build.dont_check_quantity.help"> <unit id="AzYSIiX" name="project.build.dont_check_quantity.help">
<segment state="translated"> <segment>
<source>project.build.dont_check_quantity.help</source> <source>project.build.dont_check_quantity.help</source>
<target>If this option is selected, the given withdraw quantities are used as given, no matter if more or less parts are actually required to build this project.</target> <target>If this option is selected, the given withdraw quantities are used as given, no matter if more or less parts are actually required to build this project.</target>
</segment> </segment>
</unit> </unit>
<unit id="tfOeMsC" name="part_list.action.invert_selection"> <unit id="tfOeMsC" name="part_list.action.invert_selection">
<segment state="translated"> <segment>
<source>part_list.action.invert_selection</source> <source>part_list.action.invert_selection</source>
<target>Invert selection</target> <target>Invert selection</target>
</segment> </segment>
</unit> </unit>
<unit id="vvmdRvD" name="perm.api">
<segment>
<source>perm.api</source>
<target>API</target>
</segment>
</unit>
<unit id="VrWd7Fb" name="perm.api.access_api">
<segment>
<source>perm.api.access_api</source>
<target>Access API</target>
</segment>
</unit>
<unit id="hLOM1pt" name="perm.api.manage_tokens">
<segment>
<source>perm.api.manage_tokens</source>
<target>Manage API tokens</target>
</segment>
</unit>
</file> </file>
</xliff> </xliff>