def user_grantable_permissions(session, user): """ Returns a list of permissions this user is allowed to grant. Presently, this only counts permissions that a user has directly -- in other words, the 'grant' permissions are not counted as inheritable. TODO: consider making these permissions inherited? This requires walking the graph, which is expensive. Returns a list of tuples (Permission, argument) that the user is allowed to grant. """ # avoid circular dependency from grouper.permissions import filter_grantable_permissions, get_all_permissions all_permissions = { permission.name: permission for permission in get_all_permissions(session) } if user_is_permission_admin(session, user): result = [(perm, "*") for perm in itervalues(all_permissions)] return sorted(result, key=lambda x: x[0].name + x[1]) # Someone can grant a permission if they are a member of a group that has a permission # of PERMISSION_GRANT with an argument that matches the name of a permission. grants = [ x for x in user_permissions(session, user) if x.name == PERMISSION_GRANT ] return filter_grantable_permissions(session, grants)
def post(self, name=None): tag = PublicKeyTag.get(self.session, None, name) if not tag: return self.notfound() if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name): return self.forbidden() form = PermissionGrantTagForm(self.request.arguments) form.permission.choices = [["", "(select one)"]] for perm in get_all_permissions(self.session): form.permission.choices.append( [perm.name, "{} (*)".format(perm.name)]) if not form.validate(): return self.render( "permission-grant-tag.html", form=form, tag=tag, alerts=self.get_form_alerts(form.errors), ) permission = get_permission(self.session, form.data["permission"]) if not permission: return self.notfound() # Shouldn't happen. success = grant_permission_to_tag(self.session, tag.id, permission.id, argument=form.data["argument"]) if not success: form.argument.errors.append( "Permission and Argument already mapped to this tag.") return self.render( "permission-grant-tag.html", form=form, tag=tag, alerts=self.get_form_alerts(form.errors), ) AuditLog.log( self.session, self.current_user.id, "grant_permission_tag", "Granted permission with argument: {}".format( form.data["argument"]), on_permission_id=permission.id, on_tag_id=tag.id, ) return self.redirect("/tags/{}?refresh=yes".format(tag.name))
def get(self, name=None): tag = PublicKeyTag.get(self.session, None, name) if not tag: return self.notfound() if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name): return self.forbidden() form = PermissionGrantTagForm() form.permission.choices = [["", "(select one)"]] for perm in get_all_permissions(self.session): form.permission.choices.append( [perm.name, "{} (*)".format(perm.name)]) return self.render("permission-grant-tag.html", form=form, tag=tag)
def _get_permission_tuples(session): """ Returns a set of PermissionTuple instances. """ # TODO: import here to avoid circular dependency from grouper.permissions import get_all_permissions out = set() permissions = get_all_permissions(session) for permission in permissions: out.add( PermissionTuple( id=permission.id, name=permission.name, description=permission.description, created_on=permission.created_on, audited=permission._audited, )) return out
def get(self, tag_id=None, name=None): self.handle_refresh() tag = PublicKeyTag.get(self.session, tag_id, name) if not tag: return self.notfound() permissions = get_public_key_tag_permissions(self.session, tag) log_entries = tag.my_log_entries() is_owner = user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name) can_grant = get_all_permissions(self.session) if is_owner else [] self.render( "tag.html", tag=tag, permissions=permissions, can_grant=can_grant, log_entries=log_entries, is_owner=is_owner, )
def user_grantable_permissions(session, user): """ Returns a list of permissions this user is allowed to grant. Presently, this only counts permissions that a user has directly -- in other words, the 'grant' permissions are not counted as inheritable. TODO: consider making these permissions inherited? This requires walking the graph, which is expensive. Returns a list of tuples (Permission, argument) that the user is allowed to grant. """ # avoid circular dependency from grouper.permissions import filter_grantable_permissions, get_all_permissions all_permissions = {permission.name: permission for permission in get_all_permissions(session)} if user_is_permission_admin(session, user): result = [(perm, "*") for perm in itervalues(all_permissions)] return sorted(result, key=lambda x: x[0].name + x[1]) # Someone can grant a permission if they are a member of a group that has a permission # of PERMISSION_GRANT with an argument that matches the name of a permission. grants = [x for x in user_permissions(session, user) if x.name == PERMISSION_GRANT] return filter_grantable_permissions(session, grants)
def test_permission_grant_to_owners( session, standard_graph, groups, grantable_permissions, permissions # noqa: F811 ): """Test we're getting correct owners according to granted 'grouper.permission.grant' permissions.""" perm_grant, _, perm1, perm2 = grantable_permissions # Disable the group with permission admin since otherwise they're an approver on everything, # and check that there are then no approvers. groups["permission-admins"].disable() session.commit() assert not get_owners_by_grantable_permission( session), "nothing to begin with" # grant a grant on a non-existent permission grant_permission(groups["auditors"], perm_grant, argument="notgrantable.one") assert not get_owners_by_grantable_permission( session), "ignore grants for non-existent perms" # grant a wildcard grant -- make sure all permissions are represented and # the grant isn't inherited grant_permission(groups["all-teams"], perm_grant, argument="grantable.*") owners_by_arg_by_perm = get_owners_by_grantable_permission(session) expected = [groups["all-teams"]] assert owners_by_arg_by_perm[ perm1.name]["*"] == expected, "grants are not inherited" assert len(owners_by_arg_by_perm) == 2 assert len(owners_by_arg_by_perm[perm1.name]) == 1 assert len(owners_by_arg_by_perm[perm2.name]) == 1 # grant on argument substring grant_permission(groups["team-sre"], perm_grant, argument="{}/somesubstring*".format(perm1.name)) owners_by_arg_by_perm = get_owners_by_grantable_permission(session) expected = [groups["all-teams"]] assert owners_by_arg_by_perm[perm1.name]["*"] == expected expected = [groups["team-sre"]] assert owners_by_arg_by_perm[perm1.name]["somesubstring*"] == expected # make sure get_owner() respect substrings res = [ o.groupname for o, a in get_owner_arg_list( session, perm1, "somesubstring", owners_by_arg_by_perm=owners_by_arg_by_perm) ] assert sorted(res) == ["all-teams", "team-sre" ], "should include substring wildcard matches" res = [ o.groupname for o, a in get_owner_arg_list( session, perm1, "othersubstring", owners_by_arg_by_perm=owners_by_arg_by_perm) ] assert sorted(res) == ["all-teams" ], "negative test of substring wildcard matches" # permission admins have all the power grant_permission(groups["security-team"], permissions[PERMISSION_ADMIN]) owners_by_arg_by_perm = get_owners_by_grantable_permission(session) all_permissions = get_all_permissions(session) for perm in all_permissions: assert perm.name in owners_by_arg_by_perm, "all permission should be represented" assert (groups["security-team"] in owners_by_arg_by_perm[perm.name]["*"] ), "permission admin should be wildcard owners"
def test_permission_grant_to_owners( session, standard_graph, groups, grantable_permissions, permissions # noqa: F811 ): """Test we're getting correct owners according to granted 'grouper.permission.grant' permissions.""" perm_grant, _, perm1, perm2 = grantable_permissions # Disable the group with permission admin since otherwise they're an approver on everything, # and check that there are then no approvers. groups["permission-admins"].disable() session.commit() assert not get_owners_by_grantable_permission(session), "nothing to begin with" # grant a grant on a non-existent permission grant_permission(groups["auditors"], perm_grant, argument="notgrantable.one") assert not get_owners_by_grantable_permission(session), "ignore grants for non-existent perms" # grant a wildcard grant -- make sure all permissions are represented and # the grant isn't inherited grant_permission(groups["all-teams"], perm_grant, argument="grantable.*") owners_by_arg_by_perm = get_owners_by_grantable_permission(session) expected = [groups["all-teams"]] assert owners_by_arg_by_perm[perm1.name]["*"] == expected, "grants are not inherited" assert len(owners_by_arg_by_perm) == 2 assert len(owners_by_arg_by_perm[perm1.name]) == 1 assert len(owners_by_arg_by_perm[perm2.name]) == 1 # grant on argument substring grant_permission( groups["team-sre"], perm_grant, argument="{}/somesubstring*".format(perm1.name) ) owners_by_arg_by_perm = get_owners_by_grantable_permission(session) expected = [groups["all-teams"]] assert owners_by_arg_by_perm[perm1.name]["*"] == expected expected = [groups["team-sre"]] assert owners_by_arg_by_perm[perm1.name]["somesubstring*"] == expected # make sure get_owner() respect substrings res = [ o.groupname for o, a in get_owner_arg_list( session, perm1, "somesubstring", owners_by_arg_by_perm=owners_by_arg_by_perm ) ] assert sorted(res) == ["all-teams", "team-sre"], "should include substring wildcard matches" res = [ o.groupname for o, a in get_owner_arg_list( session, perm1, "othersubstring", owners_by_arg_by_perm=owners_by_arg_by_perm ) ] assert sorted(res) == ["all-teams"], "negative test of substring wildcard matches" # permission admins have all the power grant_permission(groups["security-team"], permissions[PERMISSION_ADMIN]) owners_by_arg_by_perm = get_owners_by_grantable_permission(session) all_permissions = get_all_permissions(session) for perm in all_permissions: assert perm.name in owners_by_arg_by_perm, "all permission should be represented" assert ( groups["security-team"] in owners_by_arg_by_perm[perm.name]["*"] ), "permission admin should be wildcard owners"
def test_exclude_disabled_permissions( session, standard_graph, graph, users, groups, permissions # noqa: F811 ): """ Ensure that disabled permissions are excluded from various functions/methods that return data from the models. """ perm_ssh = get_permission(session, "ssh") perm_grant = create_permission(session, PERMISSION_GRANT) session.commit() # this user has grouper.permission.grant with argument "ssh/*" grant_permission(groups["group-admins"], perm_grant, argument="ssh/*") graph.update_from_db(session) grant_perms = [ x for x in user_permissions(session, users["*****@*****.**"]) if x.name == PERMISSION_GRANT ] assert "ssh" == filter_grantable_permissions(session, grant_perms)[0][0].name assert "ssh" in (p.name for p in get_all_permissions(session)) assert "ssh" in (p.name for p in get_all_permissions(session, include_disabled=False)) assert "ssh" in (p.name for p in get_all_permissions(session, include_disabled=True)) assert "ssh" in get_grantable_permissions(session, []) assert "team-sre" in [g[0] for g in get_groups_by_permission(session, perm_ssh)] assert get_owner_arg_list(session, perm_ssh, "*") assert "ssh" in get_owners_by_grantable_permission(session) assert "ssh" in (x[0].name for x in user_grantable_permissions(session, users["*****@*****.**"])) assert user_has_permission(session, users["*****@*****.**"], "ssh") assert "ssh" in (p.name for p in user_permissions(session, users["*****@*****.**"])) assert "ssh" in (p["permission"] for p in graph.get_group_details("team-sre")["permissions"]) assert "ssh" in (pt.name for pt in graph.get_permissions()) assert "team-sre" in graph.get_permission_details("ssh")["groups"] assert "ssh" in (p["permission"] for p in graph.get_user_details("*****@*****.**")["permissions"]) # now disable the ssh permission disable_permission(session, "ssh", users["*****@*****.**"].id) graph.update_from_db(session) grant_perms = [ x for x in user_permissions(session, users["*****@*****.**"]) if x.name == PERMISSION_GRANT ] assert not filter_grantable_permissions(session, grant_perms) assert "ssh" not in (p.name for p in get_all_permissions(session)) assert "ssh" not in (p.name for p in get_all_permissions(session, include_disabled=False)) assert "ssh" in (p.name for p in get_all_permissions(session, include_disabled=True)) assert "ssh" not in get_grantable_permissions(session, []) assert not get_groups_by_permission(session, perm_ssh) assert not get_owner_arg_list(session, perm_ssh, "*") assert "ssh" not in get_owners_by_grantable_permission(session) assert "ssh" not in ( x[0].name for x in user_grantable_permissions(session, users["*****@*****.**"]) ) assert not user_has_permission(session, users["*****@*****.**"], "ssh") assert "ssh" not in (p.name for p in user_permissions(session, users["*****@*****.**"])) assert "ssh" not in ( p["permission"] for p in graph.get_group_details("team-sre")["permissions"] ) assert "ssh" not in (pt.name for pt in graph.get_permissions()) assert not graph.get_permission_details("ssh")["groups"] assert "ssh" not in ( p["permission"] for p in graph.get_user_details("*****@*****.**")["permissions"] )