示例#1
0
def grantable_permissions(session, standard_graph):  # noqa: F811
    perm_grant = create_permission(session, PERMISSION_GRANT)
    perm0 = create_permission(session, "grantable")
    perm1 = create_permission(session, "grantable.one")
    perm2 = create_permission(session, "grantable.two")
    session.commit()

    return perm_grant, perm0, perm1, perm2
示例#2
0
def grantable_permissions(session, standard_graph):  # noqa: F811
    perm_grant = create_permission(session, PERMISSION_GRANT)
    perm0 = create_permission(session, "grantable")
    perm1 = create_permission(session, "grantable.one")
    perm2 = create_permission(session, "grantable.two")
    session.commit()

    return perm_grant, perm0, perm1, perm2
示例#3
0
def test_revoke_permission_from_tag(users, http_client, base_url, session):  # noqa: F811

    user = session.query(User).filter_by(username="******").scalar()

    create_permission(session, TAG_EDIT)
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, TAG_EDIT),
        "*",
    )

    fe_url = url(base_url, "/tags")
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"tagname": "tyler_was_here", "description": "Test Tag Please Ignore"}),
        headers={"X-Grouper-User": user.username},
    )

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, "/permissions/grant_tag/{}".format(tag.name))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"permission": TAG_EDIT, "argument": "*"}),
        headers={"X-Grouper-User": user.username},
    )

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    get_permission(session, TAG_EDIT)
    assert (
        len(get_public_key_tag_permissions(session, tag)) == 1
    ), "The tag should have exactly 1 permission"

    user = session.query(User).filter_by(username="******").scalar()

    mapping = get_public_key_tag_permissions(session, tag)[0]
    fe_url = url(base_url, "/permissions/{}/revoke_tag/{}".format(TAG_EDIT, mapping.mapping_id))
    resp = yield http_client.fetch(
        fe_url, method="POST", body="", headers={"X-Grouper-User": user.username}
    )

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    assert (
        len(get_public_key_tag_permissions(session, tag)) == 0
    ), "The tag should have no permissions"
    def post(self):
        can_create = user_creatable_permissions(self.session,
                                                self.current_user)
        if not can_create:
            return self.forbidden()

        form = PermissionCreateForm(self.request.arguments)
        if not form.validate():
            return self.render("permission-create.html",
                               form=form,
                               alerts=self.get_form_alerts(form.errors))

        # A user is allowed to create a permission if the name matches any of the globs that they
        # are given access to via PERMISSION_CREATE, as long as the permission does not match a
        # reserved name. (Unless specifically granted.)
        allowed = False
        for creatable in can_create:
            if matches_glob(creatable, form.data["name"]):
                allowed = True

        for failure_message in test_reserved_names(form.data["name"]):
            form.name.errors.append(failure_message)

        if not allowed:
            form.name.errors.append(
                "Permission name does not match any of your allowed patterns.")

        if form.name.errors:
            return self.render("permission-create.html",
                               form=form,
                               alerts=self.get_form_alerts(form.errors))

        try:
            permission = create_permission(self.session, form.data["name"],
                                           form.data["description"])
            self.session.flush()
        except IntegrityError:
            self.session.rollback()
            form.name.errors.append(
                "Name already in use. Permissions must be unique.")
            return self.render(
                "permission-create.html",
                form=form,
                can_create=can_create,
                alerts=self.get_form_alerts(form.errors),
            )

        self.session.commit()

        AuditLog.log(
            self.session,
            self.current_user.id,
            "create_permission",
            "Created permission.",
            on_permission_id=permission.id,
        )

        # No explicit refresh because handler queries SQL.
        return self.redirect("/permissions/{}".format(permission.name))
示例#5
0
def test_grant_permission_to_tag(users, http_client, base_url, session):  # noqa: F811

    user = session.query(User).filter_by(username="******").scalar()

    perm = create_permission(session, TAG_EDIT)
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, TAG_EDIT),
        "*",
    )

    fe_url = url(base_url, "/tags")
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"tagname": "tyler_was_here", "description": "Test Tag Please Ignore"}),
        headers={"X-Grouper-User": user.username},
    )

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, "/permissions/grant_tag/{}".format(tag.name))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"permission": TAG_EDIT, "argument": "*"}),
        headers={"X-Grouper-User": user.username},
    )

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    perm = get_permission(session, TAG_EDIT)
    assert (
        len(get_public_key_tag_permissions(session, tag)) == 1
    ), "The tag should have exactly 1 permission"
    assert (
        get_public_key_tag_permissions(session, tag)[0].name == perm.name
    ), "The tag's permission should be the one we added"
    assert (
        get_public_key_tag_permissions(session, tag)[0].argument == "*"
    ), "The tag's permission should be the one we added"

    # Make sure trying to add a permission to a tag doesn't fail horribly if it's already there
    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, "/permissions/grant_tag/{}".format(tag.name))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"permission": TAG_EDIT, "argument": "*"}),
        headers={"X-Grouper-User": user.username},
    )

    assert resp.code == 200
示例#6
0
    def post(self):
        can_create = user_creatable_permissions(self.session, self.current_user)
        if not can_create:
            return self.forbidden()

        form = PermissionCreateForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "permission-create.html", form=form, alerts=self.get_form_alerts(form.errors)
            )

        # A user is allowed to create a permission if the name matches any of the globs that they
        # are given access to via PERMISSION_CREATE, as long as the permission does not match a
        # reserved name. (Unless specifically granted.)
        allowed = False
        for creatable in can_create:
            if matches_glob(creatable, form.data["name"]):
                allowed = True

        for failure_message in test_reserved_names(form.data["name"]):
            form.name.errors.append(failure_message)

        if not allowed:
            form.name.errors.append("Permission name does not match any of your allowed patterns.")

        if form.name.errors:
            return self.render(
                "permission-create.html", form=form, alerts=self.get_form_alerts(form.errors)
            )

        try:
            permission = create_permission(
                self.session, form.data["name"], form.data["description"]
            )
            self.session.flush()
        except IntegrityError:
            self.session.rollback()
            form.name.errors.append("Name already in use. Permissions must be unique.")
            return self.render(
                "permission-create.html",
                form=form,
                can_create=sorted(can_create),
                alerts=self.get_form_alerts(form.errors),
            )

        self.session.commit()

        AuditLog.log(
            self.session,
            self.current_user.id,
            "create_permission",
            "Created permission.",
            on_permission_id=permission.id,
        )

        # No explicit refresh because handler queries SQL.
        return self.redirect("/permissions/{}".format(permission.name))
示例#7
0
def test_edit_tag(users, http_client, base_url, session):  # noqa: F811

    user = session.query(User).filter_by(username="******").scalar()

    create_permission(session, TAG_EDIT)
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, TAG_EDIT),
        "*",
    )

    fe_url = url(base_url, "/tags")
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({
            "tagname": "tyler_was_here",
            "description": "Test Tag Please Ignore"
        }),
        headers={"X-Grouper-User": user.username},
    )

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    assert (tag.description == "Test Tag Please Ignore"
            ), "The description should match what we created it with"

    user = session.query(User).filter_by(username="******").scalar()
    fe_url = url(base_url, "/tags/{}/edit".format(tag.id))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"description": "Don't tag me bro"}),
        headers={"X-Grouper-User": user.username},
    )

    assert resp.code == 200

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    assert tag.description == "Don't tag me bro", "The description should have been updated"
示例#8
0
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"

    class FakePermissionAliasesPlugin(BasePlugin):
        def get_aliases_for_mapped_permission(self, session, permission,
                                              argument):
            # type: (Session, str, str) -> List[Tuple[str, str]]
            if permission != "alias_perm" or argument != "team-sre":
                return []
            return [(PERMISSION_GRANT, "foo-perm/bar-arg")]

    owner_perm = create_permission(session, "alias_perm")
    session.commit()
    get_plugin_proxy().add_plugin(FakePermissionAliasesPlugin())
    grant_permission(groups["team-sre"], owner_perm, "team-sre")
    owners_by_arg_by_perm = get_owners_by_grantable_permission(session)
    expected = [groups["team-sre"]]
    assert owners_by_arg_by_perm["foo-perm"]["bar-arg"] == expected

    # 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"
示例#9
0
def test_permissions(users, http_client, base_url, session):  # noqa: F811

    user = session.query(User).filter_by(username="******").scalar()

    create_permission(session, TAG_EDIT)
    session.commit()

    create_permission(session, "it.literally.does.not.matter")
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, TAG_EDIT),
        "*",
    )
    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, "it.literally.does.not.matter"),
        "*",
    )

    fe_url = url(base_url, "/tags")
    yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"tagname": "tyler_was_here", "description": "Test Tag Please Ignore"}),
        headers={"X-Grouper-User": user.username},
    )

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, "/permissions/grant_tag/{}".format(tag.name))
    yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"permission": TAG_EDIT, "argument": "prod"}),
        headers={"X-Grouper-User": user.username},
    )

    user = session.query(User).filter_by(username="******").scalar()
    # add SSH key
    fe_url = url(base_url, "/users/{}/public-key/add".format(user.username))
    yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"public_key": SSH_KEY_1}),
        headers={"X-Grouper-User": user.username},
    )

    key = session.query(PublicKey).filter_by(user_id=user.id).scalar()
    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, "/users/{}/public-key/{}/tag".format(user.username, key.id))
    yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"tagname": "tyler_was_here"}),
        headers={"X-Grouper-User": user.username},
    )

    user = session.query(User).filter_by(username="******").scalar()

    key = session.query(PublicKey).filter_by(user_id=user.id).scalar()
    assert (
        len(get_public_key_permissions(session, key)) == 1
    ), "The SSH Key should have only 1 permission"
    assert (
        get_public_key_permissions(session, key)[0].name == TAG_EDIT
    ), "The SSH key's permission should be TAG_EDIT"
    assert (
        get_public_key_permissions(session, key)[0].argument == "prod"
    ), "The SSH key's permission argument should be restricted to the tag's argument"
    assert len(user_permissions(session, user)) > 1, "The user should have more than 1 permission"
示例#10
0
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"]
    )
示例#11
0
def sync_db_command(args):
    # Models not implicitly or explictly imported above are explicitly imported here
    from grouper.models.perf_profile import PerfProfile  # noqa: F401

    db_engine = get_db_engine(get_database_url(settings))
    Model.metadata.create_all(db_engine)

    # Add some basic database structures we know we will need if they don't exist.
    session = make_session()

    for name, description in SYSTEM_PERMISSIONS:
        test = get_permission(session, name)
        if test:
            continue
        try:
            create_permission(session, name, description)
            session.flush()
        except IntegrityError:
            session.rollback()
            raise Exception("Failed to create permission: %s" % (name, ))
        session.commit()

    # This group is needed to bootstrap a Grouper installation.
    admin_group = Group.get(session, name="grouper-administrators")
    if not admin_group:
        admin_group = Group(
            groupname="grouper-administrators",
            description="Administrators of the Grouper system.",
            canjoin="nobody",
        )

        try:
            admin_group.add(session)
            session.flush()
        except IntegrityError:
            session.rollback()
            raise Exception("Failed to create group: grouper-administrators")

        for permission_name in (GROUP_ADMIN, PERMISSION_ADMIN, USER_ADMIN):
            permission = get_permission(session, permission_name)
            assert permission, "Permission should have been created earlier!"
            grant_permission(session, admin_group.id, permission.id)

        session.commit()

    auditors_group_name = get_auditors_group_name(settings)
    auditors_group = Group.get(session, name=auditors_group_name)
    if not auditors_group:
        auditors_group = Group(
            groupname=auditors_group_name,
            description=
            "Group for auditors, who can be owners of audited groups.",
            canjoin="canjoin",
        )

        try:
            auditors_group.add(session)
            session.flush()
        except IntegrityError:
            session.rollback()
            raise Exception(
                "Failed to create group: {}".format(auditors_group_name))

        permission = get_permission(session, PERMISSION_AUDITOR)
        assert permission, "Permission should have been created earlier!"
        grant_permission(session, auditors_group.id, permission.id)

        session.commit()
示例#12
0
def test_tags(session, http_client, base_url, graph):  # noqa: F811
    perm = create_permission(session, TAG_EDIT)
    session.commit()

    create_permission(session, "it.literally.does.not.matter")
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, TAG_EDIT),
        "*",
    )
    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, "it.literally.does.not.matter"),
        "*",
    )

    tag = PublicKeyTag(name="tyler_was_here")
    tag.add(session)
    session.commit()

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    grant_permission_to_tag(session, tag.id, perm.id, "prod")
    with pytest.raises(AssertionError):
        grant_permission_to_tag(session, tag.id, perm.id, "question?")

    user = session.query(User).filter_by(username="******").scalar()

    add_public_key(session, user, SSH_KEY_1)

    key = session.query(PublicKey).filter_by(user_id=user.id).scalar()

    add_tag_to_public_key(session, key, tag)

    user = session.query(User).filter_by(username="******").scalar()

    key = session.query(PublicKey).filter_by(user_id=user.id).scalar()
    assert (
        len(get_public_key_permissions(session, key)) == 1
    ), "The SSH Key should have only 1 permission"
    assert (
        get_public_key_permissions(session, key)[0].name == TAG_EDIT
    ), "The SSH key's permission should be TAG_EDIT"
    assert (
        get_public_key_permissions(session, key)[0].argument == "prod"
    ), "The SSH key's permission argument should be restricted to the tag's argument"
    assert len(user_permissions(session, user)) > 1, "The user should have more than 1 permission"

    graph.update_from_db(session)

    fe_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    pub_key = body["data"]["user"]["public_keys"][0]
    assert len(pub_key["tags"]) == 1, "The public key should only have 1 tag"
    assert pub_key["fingerprint"] == "e9:ae:c5:8f:39:9b:3a:9c:6a:b8:33:6b:cb:6f:ba:35"
    assert pub_key["fingerprint_sha256"] == "MP9uWaujW96EWxbjDtPdPWheoMDu6BZ8FZj0+CBkVWU"
    assert pub_key["tags"][0] == "tyler_was_here", "The public key should have the tag we gave it"