Repository: privacyidea/privacyidea

Issue:
Hide buttons instead of disabling them
Open to discussion:

If a user or admin are not allowed to delete or revoke tokens per
policy, maybe we should not display the delete buttons at all. Currently
they are shown as disabled (light color buttons).



Discussion:
I think, hiding the buttons is a good idea. It reduces the information overload for users/admins and showing a disabled button does not provide any more information.
Showing disabled buttons may be useful if the user/admin is generally allowed to do this action but not in this special case (not token owner, ...).
This is an interesting point. And I think this was the reason to disable the buttons in the first place. 
We can not say, if the admin would be allowed e.g. to disable a token in other circumstances. Sometimes the admin would wonder, "where the heck can I disable the a token?".

As he acutally sees the disabled button, he knows, that he is not allowed to disable a token. If the button is hidden, he might think, he does not find the spot, where he can disable the token.

Maybe it would be wise to choose, if buttons should be disabled or hidden. There are good reasons to hide buttons and other good reasons to disable buttons.
The buttons in the UI are hidden this way:


    ng-disabled="!checkRight('revoke')"


We can add ``ng-show="false"``, to hide the button.
To get the False value, we can add a webui policy like "hide_instead_of_disable" (name to be improved! ;-) 

We either would enhance the function ``checkRight`` - but this is imho a bad idea, since the name implies another outcome - or we add a new function ``hideButton`` or we simply add


    ng-hide="!checkRight('revoke') && checkRight('hide_instead_of_disable')"


Resolving patch:
diff --git a/privacyidea/api/lib/postpolicy.py b/privacyidea/api/lib/postpolicy.py
--- a/privacyidea/api/lib/postpolicy.py
+++ b/privacyidea/api/lib/postpolicy.py
@@ -580,6 +580,14 @@ def get_webui_settings(request, response):
             active=True
         )
         hide_welcome = bool(hide_welcome)
+        hide_buttons = policy_object.get_policies(
+            action=ACTION.HIDE_BUTTONS,
+            scope=SCOPE.WEBUI,
+            realm=realm,
+            client=client,
+            active=True,
+        )
+        hide_buttons = bool(hide_buttons)
         default_tokentype_pol = policy_object.get_action_values(
             action=ACTION.DEFAULT_TOKENTYPE,
             scope=SCOPE.WEBUI,
@@ -635,6 +643,7 @@ def get_webui_settings(request, response):
         content["result"]["value"]["search_on_enter"] = len(search_on_enter) > 0
         content["result"]["value"]["timeout_action"] = timeout_action
         content["result"]["value"]["hide_welcome"] = hide_welcome
+        content["result"]["value"]["hide_buttons"] = hide_buttons
         content["result"]["value"]["show_seed"] = show_seed
         content["result"]["value"]["subscription_status"] = subscription_status()
         response.data = json.dumps(content)
diff --git a/privacyidea/lib/policy.py b/privacyidea/lib/policy.py
--- a/privacyidea/lib/policy.py
+++ b/privacyidea/lib/policy.py
@@ -308,6 +308,7 @@ class ACTION(object):
     SEARCH_ON_ENTER = "search_on_enter"
     TIMEOUT_ACTION = "timeout_action"
     AUTH_CACHE = "auth_cache"
+    HIDE_BUTTONS = "hide_buttons"
     HIDE_WELCOME = "hide_welcome_info"
     SHOW_SEED = "show_seed"
     CUSTOM_MENU = "custom_menu"
@@ -1767,6 +1768,11 @@ def get_static_policy_definitions(scope=None):
                 'desc': _("If this checked, the administrator will not see "
                           "the welcome dialog anymore.")
             },
+            ACTION.HIDE_BUTTONS: {
+                'type': 'bool',
+                'desc': _("Per default disabled actions result in disabled buttons. When"
+                          " checking this action, buttons of disabled actions are hidden.")
+            },
             ACTION.SHOW_SEED: {
                 'type': 'bool',
                 'desc': _("If this is checked, the seed "


Test patch: