Module: check_mk
Branch: master
Commit: 07250cc7a9f02477a53b09b561d45600fe702186
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=07250cc7a9f024…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Mon Apr 25 13:14:24 2016 +0200
Views/Dashboards: Can now be published to members of specific contact groups
---
web/htdocs/userdb.py | 20 ++++++++++++++++++++
web/htdocs/views.py | 4 ++--
web/htdocs/visuals.py | 49 ++++++++++++++++++++++++++++++++++++-------------
web/htdocs/wato.py | 17 +++--------------
4 files changed, 61 insertions(+), 29 deletions(-)
diff --git a/web/htdocs/userdb.py b/web/htdocs/userdb.py
index 61123ba..5b2240e 100644
--- a/web/htdocs/userdb.py
+++ b/web/htdocs/userdb.py
@@ -707,6 +707,7 @@ def load_roles():
# | \____|_| \___/ \__,_| .__/|___/ |
# | |_| |
# +----------------------------------------------------------------------+
+# TODO: Contact groups are fine here, but service / host groups?
def load_group_information():
try:
@@ -754,6 +755,25 @@ def load_group_information():
'Initializing structure...' % (filename, e))
return {}
+
+class GroupChoice(DualListChoice):
+ def __init__(self, what, **kwargs):
+ DualListChoice.__init__(self, **kwargs)
+ self.what = what
+ self._choices = lambda: self.load_groups()
+
+ def load_groups(self):
+ all_groups = load_group_information()
+ this_group = all_groups.get(self.what, {})
+ return [ (k, t['alias'] and t['alias'] or k) for (k, t) in
this_group.items() ]
+
+
+# TODO: This is not performing good with a large user base. Hope it works for our needs.
+# Maybe we need to change it to livestatus or change our data structures somehow in the
future.
+def groups_of_user(user_id):
+ users = load_users(lock=False)
+ return users[user_id]["contactgroups"]
+
#.
# .-Custom-Attrs.--------------------------------------------------------.
# | ____ _ _ _ _ |
diff --git a/web/htdocs/views.py b/web/htdocs/views.py
index 71de7d2..b87767e 100644
--- a/web/htdocs/views.py
+++ b/web/htdocs/views.py
@@ -725,10 +725,10 @@ def transform_view_to_valuespec_value(view):
if view.get(key):
view['view']['options'].append(key)
- view['visibility'] = []
+ view['visibility'] = {}
for key in [ 'hidden', 'hidebutton', 'public' ]:
if view.get(key):
- view['visibility'].append(key)
+ view['visibility'][key] = view[key]
view['grouping'] = { "grouping" :
view.get('group_painters', []) }
view['sorting'] = { "sorters" : view.get('sorters', {}) }
diff --git a/web/htdocs/visuals.py b/web/htdocs/visuals.py
index 13e07b5..4a2cd0b 100644
--- a/web/htdocs/visuals.py
+++ b/web/htdocs/visuals.py
@@ -212,6 +212,17 @@ def available(what, all_visuals):
visuals = {}
permprefix = what[:-1]
+ def published_to_user(visual):
+ if visual["public"] == True:
+ return True
+
+ if type(visual["public"]) == tuple and visual["public"][0] ==
"contact_groups":
+ user_groups = set(userdb.groups_of_user(user))
+ if user_groups.intersection(visual["public"][1]):
+ return True
+
+ return False
+
# 1. user's own visuals, if allowed to edit visuals
if config.may("general.edit_" + what):
for (u, n), visual in all_visuals.items():
@@ -220,7 +231,7 @@ def available(what, all_visuals):
# 2. visuals of special users allowed to globally override builtin visuals
for (u, n), visual in all_visuals.items():
- if n not in visuals and visual["public"] and config.user_may(u,
"general.force_" + what):
+ if n not in visuals and published_to_user(visual) and config.user_may(u,
"general.force_" + what):
# Honor original permissions for the current user
permname = "%s.%s" % (permprefix, n)
if config.permission_exists(permname) \
@@ -238,7 +249,7 @@ def available(what, all_visuals):
# necessary.
if config.may("general.see_user_" + what):
for (u, n), visual in all_visuals.items():
- if n not in visuals and visual["public"] and config.user_may(u,
"general.publish_" + what):
+ if n not in visuals and published_to_user(visual) and config.user_may(u,
"general.publish_" + what):
# Is there a builtin visual with the same name? If yes, honor
permissions.
permname = "%s.%s" % (permprefix, n)
if config.permission_exists(permname) \
@@ -635,13 +646,25 @@ def page_edit_visual(what, all_visuals, custom_field_handler =
None,
# A few checkboxes concerning the visibility of the visual. These will
# appear as boolean-keys directly in the visual dict, but encapsulated
# in a list choice in the value spec.
- visibility_choices = [
- ('hidden', _('Hide this %s from the sidebar') %
visual_type["title"]),
- ('hidebutton', _('Do not show a context button to this %s') %
visual_type["title"]),
+ visibility_elements = [
+ ('hidden', FixedValue(None,
+ title = _('Hide this %s from the sidebar') %
visual_type["title"],
+ )),
+ ('hidebutton', FixedValue(None,
+ title = _('Do not show a context button to this %s') %
visual_type["title"],
+ )),
]
if config.may("general.publish_" + what):
- visibility_choices.append(
- ('public', _('Make this %s available for all users') %
visual_type["title"]))
+ visibility_elements.append(('public', CascadingDropdown(
+ choices = [
+ (True, _("Publish to all users")),
+ ("contact_groups", _("Publish to members of contact
groups"), userdb.GroupChoice(
+ "contact",
+ title = _("Publish to members of contact groups"),
+ )),
+ ],
+ title = _('Make this %s available for other users') %
visual_type["title"]
+ )))
vs_general = Dictionary(
title = _("General Properties"),
@@ -677,9 +700,9 @@ def page_edit_visual(what, all_visuals, custom_field_handler = None,
('icon', IconSelector(
title = _('Button Icon'),
)),
- ('visibility', ListChoice(
+ ('visibility', Dictionary(
title = _('Visibility'),
- choices = visibility_choices,
+ elements = visibility_elements,
)),
],
)
@@ -712,8 +735,8 @@ def page_edit_visual(what, all_visuals, custom_field_handler = None,
visual[key] = general_properties[key]
# ...and import the visibility flags directly into the visual
- for key, title in visibility_choices:
- visual[key] = key in general_properties['visibility']
+ for key in dict(visibility_elements).keys():
+ visual[key] = general_properties['visibility'].get(key, False)
if not config.may("general.publish_" + what):
visual['public'] = False
@@ -763,8 +786,8 @@ def page_edit_visual(what, all_visuals, custom_field_handler = None,
# FIXME: Hier werden die Flags aus visibility nicht korrekt geladen. Wäre es nicht
besser,
# diese in einem Unter-Dict zu lassen, anstatt diese extra umzukopieren?
- visib = []
- for key, title in visibility_choices:
+ visib = {}
+ for key, vs in visibility_elements:
if visual.get(key):
visib.append(key)
visual["visibility"] = visib
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index 187a677..a92b6e8 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -6911,17 +6911,6 @@ def FolderChoice(**kwargs):
return DropdownChoice(**kwargs)
-class GroupChoice(DualListChoice):
- def __init__(self, what, **kwargs):
- DualListChoice.__init__(self, **kwargs)
- self.what = what
- self._choices = lambda: self.load_groups()
-
- def load_groups(self):
- all_groups = userdb.load_group_information()
- this_group = all_groups.get(self.what, {})
- return [ (k, t['alias'] and t['alias'] or k) for (k, t) in
this_group.items() ]
-
def vs_notification_bulkby():
return ListChoice(
title = _("Create separate notification bulks based on"),
@@ -7182,7 +7171,7 @@ def simple_host_rule_match_conditions():
title = _("Match Host Tags"))
),
( "match_hostgroups",
- GroupChoice("host",
+ userdb.GroupChoice("host",
title = _("Match Host Groups"),
help = _("The host must be in one of the selected host groups"),
allow_empty = False,
@@ -7210,7 +7199,7 @@ def simple_host_rule_match_conditions():
def generic_rule_match_conditions():
return simple_host_rule_match_conditions() + [
( "match_servicegroups",
- GroupChoice("service",
+ userdb.GroupChoice("service",
title = _("Match Service Groups"),
help = _("The service must be in one of the selected service groups.
For host events this condition "
"never matches as soon as at least one group is
selected."),
@@ -7261,7 +7250,7 @@ def generic_rule_match_conditions():
)
),
( "match_contactgroups",
- GroupChoice("contact",
+ userdb.GroupChoice("contact",
title = _("Match Contact Groups"),
help = _("The host/service must be in one of the selected contact
groups. This only works with Check_MK Micro Core. " \
"If you don't use the CMC that filter will not
apply"),