Exemple #1
0
def test_oneoff(mock_make_session, mock_annex, session):
    mock_make_session.return_value = session
    username = '******'
    other_username = '******'
    groupname = 'fake_group'

    class FakeOneOff(object):
        def configure(self, service_name):
            pass

        def run(self, session, **kwargs):
            if kwargs.get('group'):
                Group.get_or_create(session, groupname=groupname)
                session.commit()
            elif kwargs.get('key') == 'valuewith=':
                User.get_or_create(session, username=other_username)
                session.commit()
            else:
                User.get_or_create(session, username=username)
                session.commit()

    mock_annex.return_value = [FakeOneOff()]

    # dry_run
    call_main('oneoff', 'run', 'FakeOneOff')
    assert User.get(session,
                    name=username) is None, 'default dry_run means no writes'
    assert User.get(session,
                    name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(
        session,
        name=groupname) is None, '"group" not in arg so no group created'

    # not dry_run, create a user
    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff')
    assert User.get(session,
                    name=username) is not None, 'dry_run off means writes'
    assert User.get(session,
                    name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(
        session,
        name=groupname) is None, '"group" not in arg so no group created'

    # not dry_run, use kwarg to create a group
    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'group=1')
    assert User.get(session,
                    name=username) is not None, 'dry_run off means writes'
    assert User.get(session,
                    name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(
        session, name=groupname) is not None, '"group" in arg so group created'

    # invalid format for argument should result in premature system exit
    with pytest.raises(SystemExit):
        call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'bad_arg')

    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'key=valuewith=')
    assert User.get(
        session,
        name=other_username) is not None, '"valuewith= in arg, create user2'
Exemple #2
0
def test_group_add_remove_owner(
        make_session,
        get_plugin_proxy,
        session,
        users,
        groups  # noqa: F811
):
    make_session.return_value = session
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

    username = "******"
    groupname = "team-sre"

    # add
    assert (u"User", username) not in groups[groupname].my_members()
    call_main(session, "group", "add_member", "--owner", groupname, username)
    all_members = Group.get(session, name=groupname).my_members()
    assert (u"User", username) in all_members
    _, _, _, role, _, _ = all_members[(u"User", username)]
    assert GROUP_EDGE_ROLES[role] == "owner"

    # remove (fails)
    call_main(session, "group", "remove_member", groupname, username)
    assert (u"User", username) in Group.get(session,
                                            name=groupname).my_members()
def test_sa_pubkeys(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    create_role_user(session, user, '*****@*****.**', 'Hi', 'canjoin')

    u = User.get(session, name="*****@*****.**")
    g = Group.get(session, name="*****@*****.**")

    assert u is not None
    assert g is not None
    assert is_role_user(session, user=u)
    assert is_role_user(session, group=g)
    assert get_role_user(session, user=u).group.id == g.id
    assert get_role_user(session, group=g).user.id == u.id
    assert not is_role_user(session, user=user)
    assert not is_role_user(session, group=Group.get(session, name="team-sre"))

    assert not get_public_keys_of_user(session, user.id)

    with pytest.raises(HTTPError):
        # add it
        fe_url = url(base_url, '/users/{}/public-key/add'.format("*****@*****.**"))
        resp = yield http_client.fetch(fe_url, method="POST",
                body=urlencode({'public_key': SSH_KEY_1}),
                headers={'X-Grouper-User': "******"})

    # add it
    fe_url = url(base_url, '/users/{}/public-key/add'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'public_key': SSH_KEY_1}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    # add bad key -- shouldn't add
    fe_url = url(base_url, '/users/{}/public-key/add'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'public_key': SSH_KEY_BAD}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    sa = User.get(session, name="*****@*****.**")
    keys = get_public_keys_of_user(session, sa.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_1

    with pytest.raises(HTTPError):
        # delete it
        fe_url = url(base_url, '/users/{}/public-key/{}/delete'.format("*****@*****.**", keys[0].id))
        resp = yield http_client.fetch(fe_url, method="POST", body='',
                headers={'X-Grouper-User': "******"})

    # delete it
    fe_url = url(base_url, '/users/{}/public-key/{}/delete'.format("*****@*****.**", keys[0].id))
    resp = yield http_client.fetch(fe_url, method="POST", body='',
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    sa = User.get(session, name="*****@*****.**")
    assert not get_public_keys_of_user(session, sa.id)
Exemple #4
0
def test_sync_db_default_group(
        mock_get_auditors_group_name,
        make_session,
        session,
        users,
        groups  # noqa: F811
):
    make_session.return_value = session

    auditors_group = Group.get(session, name="my-auditors")
    assert not auditors_group, "Auditors group should not exist yet"

    call_main(session, "sync_db")
    admin_group = Group.get(session, name="grouper-administrators")
    assert admin_group, "Group should have been autocreated"

    admin_group_permission_names = [
        perm[1] for perm in admin_group.my_permissions()
    ]
    for permission in (GROUP_ADMIN, PERMISSION_ADMIN, USER_ADMIN):
        assert permission in admin_group_permission_names, (
            "Expected permission missing: %s" % permission)

    auditors_group = Group.get(session, name="my-auditors")
    assert auditors_group, "Auditors group should have been autocreated"
    auditors_group_permission_names = [
        perm[1] for perm in auditors_group.my_permissions()
    ]
    assert PERMISSION_AUDITOR in auditors_group_permission_names, (
        "Expected permission missing: %s" % PERMISSION_AUDITOR)
def test_sa_tokens(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    create_role_user(session, user, '*****@*****.**', 'Hi', 'canjoin')

    u = User.get(session, name="*****@*****.**")
    g = Group.get(session, name="*****@*****.**")

    assert u is not None
    assert g is not None
    assert is_role_user(session, user=u)
    assert is_role_user(session, group=g)
    assert get_role_user(session, user=u).group.id == g.id
    assert get_role_user(session, group=g).user.id == u.id
    assert not is_role_user(session, user=user)
    assert not is_role_user(session, group=Group.get(session, name="team-sre"))

    with pytest.raises(HTTPError):
        # Add token
        fe_url = url(base_url, '/users/{}/tokens/add'.format("*****@*****.**"))
        resp = yield http_client.fetch(fe_url, method="POST",
                body=urlencode({'name': 'myDHDToken'}),
                headers={'X-Grouper-User': "******"})

    # Add token
    fe_url = url(base_url, '/users/{}/tokens/add'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({'name': 'myDHDToken'}),
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    # Verify add
    fe_url = url(base_url, '/users/{}'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="GET",
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200
    assert "Added token: myDHDToken" in resp.body

    with pytest.raises(HTTPError):
        # Disable token
        fe_url = url(base_url, '/users/{}/tokens/1/disable'.format("*****@*****.**"))
        resp = yield http_client.fetch(fe_url, method="POST",
                body="",
                headers={'X-Grouper-User': "******"})

    # Disable token
    fe_url = url(base_url, '/users/{}/tokens/1/disable'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="POST",
            body="",
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    # Verify disable
    fe_url = url(base_url, '/users/{}'.format("*****@*****.**"))
    resp = yield http_client.fetch(fe_url, method="GET",
            headers={'X-Grouper-User': user.username})
    assert resp.code == 200
    assert "Disabled token: myDHDToken" in resp.body
Exemple #6
0
    def post(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

        group = Group.get(self.session, name=name)
        if not group:
            return self.notfound()

        if not user_can_manage_group(self.session, group, self.current_user):
            return self.forbidden()

        form = GroupEditForm(self.request.arguments, obj=group)
        if not form.validate():
            return self.render("group-edit.html",
                               group=group,
                               form=form,
                               alerts=self.get_form_alerts(form.errors))

        new_name = form.data["groupname"]
        renamed = group.groupname != new_name

        if renamed and is_role_user(self.session, group=group):
            form.groupname.errors.append(
                "You cannot change the name of service account groups")
            return self.render("group-edit.html",
                               group=group,
                               form=form,
                               alerts=self.get_form_alerts(form.errors))

        if renamed and Group.get(self.session, name=new_name):
            message = f"A group named '{new_name}' already exists (possibly disabled)"
            form.groupname.errors.append(message)
            return self.render("group-edit.html",
                               group=group,
                               form=form,
                               alerts=self.get_form_alerts(form.errors))

        group.groupname = new_name
        group.email_address = form.data["email_address"]
        group.description = form.data["description"]
        group.canjoin = form.data["canjoin"]
        group.auto_expire = form.data["auto_expire"]
        group.require_clickthru_tojoin = form.data["require_clickthru_tojoin"]
        Counter.incr(self.session, "updates")
        self.session.commit()

        AuditLog.log(self.session,
                     self.current_user.id,
                     "edit_group",
                     "Edited group.",
                     on_group_id=group.id)

        url = f"/groups/{group.name}"
        if renamed:
            url += "?refresh=yes"
        self.redirect(url)
Exemple #7
0
def test_group_name_checks(session, tmpdir, users, groups):  # noqa: F811
    username = "******"
    groupname = "team-sre"

    # check user/group name
    call_main(session, tmpdir, "group", "add_member", "--member", "invalid group name", username)
    assert (u"User", username) not in Group.get(session, name=groupname).my_members()

    bad_username = "******"
    call_main(session, tmpdir, "group", "add_member", "--member", groupname, bad_username)
    assert (u"User", bad_username) not in Group.get(session, name=groupname).my_members()
Exemple #8
0
def test_group_disable_group_owner(get_plugin_proxy, session, tmpdir, users, groups):  # noqa: F811
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

    username = "******"
    groupname = "team-sre"

    # add
    call_main(session, tmpdir, "group", "add_member", "--owner", groupname, username)
    assert (u"User", username) in Group.get(session, name=groupname).my_members()

    # disable (fails)
    call_main(session, tmpdir, "user", "disable", username)
    assert (u"User", username) in Group.get(session, name=groupname).my_members()
Exemple #9
0
def test_group_bulk_add_remove(session, tmpdir, users, groups):  # noqa: F811
    groupname = "team-sre"

    # bulk add
    usernames = {"*****@*****.**", "*****@*****.**", "*****@*****.**"}
    call_main(session, tmpdir, "group", "add_member", "--member", groupname, *usernames)
    members = {u for _, u in Group.get(session, name=groupname).my_members()}
    assert usernames.issubset(members)

    # bulk remove
    call_main(session, tmpdir, "group", "remove_member", groupname, *usernames)
    members = {u for _, u in Group.get(session, name=groupname).my_members()}
    assert not members.intersection(usernames)
def test_group_name_checks(make_session, session, users, groups):
    make_session.return_value = session

    username = '******'
    groupname = 'team-sre'

    # check user/group name
    call_main('group', 'add_member', '--member', 'invalid group name', username)
    assert (u'User', username) not in Group.get(session, name=groupname).my_members()

    bad_username = '******'
    call_main('group', 'add_member', '--member', groupname, bad_username)
    assert (u'User', bad_username) not in Group.get(session, name=groupname).my_members()
Exemple #11
0
def test_group_name_checks(make_session, session, users, groups):  # noqa: F811
    make_session.return_value = session

    username = "******"
    groupname = "team-sre"

    # check user/group name
    call_main(session, "group", "add_member", "--member", "invalid group name", username)
    assert (u"User", username) not in Group.get(session, name=groupname).my_members()

    bad_username = "******"
    call_main(session, "group", "add_member", "--member", groupname, bad_username)
    assert (u"User", bad_username) not in Group.get(session, name=groupname).my_members()
Exemple #12
0
def test_group_bulk_add_remove(session, tmpdir, users, groups):  # noqa: F811
    groupname = "team-sre"

    # bulk add
    usernames = {"*****@*****.**", "*****@*****.**", "*****@*****.**"}
    call_main(session, tmpdir, "group", "add_member", "--member", groupname,
              *usernames)
    members = {u for _, u in Group.get(session, name=groupname).my_members()}
    assert usernames.issubset(members)

    # bulk remove
    call_main(session, tmpdir, "group", "remove_member", groupname, *usernames)
    members = {u for _, u in Group.get(session, name=groupname).my_members()}
    assert not members.intersection(usernames)
def test_group_bulk_add_remove(make_session, session, users, groups):
    make_session.return_value = session

    groupname = 'team-sre'

    # bulk add
    usernames = {'*****@*****.**', '*****@*****.**', '*****@*****.**'}
    call_main('group', 'add_member', '--member', groupname, *usernames)
    members = {u for _, u in Group.get(session, name=groupname).my_members().keys()}
    assert usernames.issubset(members)

    # bulk remove
    call_main('group', 'remove_member', groupname, *usernames)
    members = {u for _, u in Group.get(session, name=groupname).my_members().keys()}
    assert not members.intersection(usernames)
Exemple #14
0
def test_group_add_remove_member(session, tmpdir, users, groups):  # noqa: F811
    username = "******"
    groupname = "team-sre"

    # add
    assert (u"User", username) not in groups[groupname].my_members()
    call_main(session, tmpdir, "group", "add_member", "--member", groupname, username)
    all_members = Group.get(session, name=groupname).my_members()
    assert (u"User", username) in all_members
    _, _, _, role, _, _ = all_members[(u"User", username)]
    assert GROUP_EDGE_ROLES[role] == "member"

    # remove
    call_main(session, tmpdir, "group", "remove_member", groupname, username)
    assert (u"User", username) not in Group.get(session, name=groupname).my_members()
def test_create(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.add_user_to_group("*****@*****.**", "other-group")

    run_ctl(
        setup,
        "service_account",
        "--actor",
        "*****@*****.**",
        "create",
        "*****@*****.**",
        "some-group",
        "foo +bar -(org)",
        "this is a service account.\n\n it is for testing",
    )
    service_account = ServiceAccount.get(setup.session,
                                         name="*****@*****.**")
    assert service_account is not None
    assert service_account.user.name == "*****@*****.**"
    assert service_account.machine_set == "foo +bar -(org)"
    assert service_account.description == "this is a service account.\n\n it is for testing"
    group = Group.get(setup.session, name="some-group")
    assert group
    assert get_service_accounts(setup.session, group) == [service_account]

    # If the account already exists, creating it again returns an error and does nothing.
    with pytest.raises(SystemExit):
        run_ctl(
            setup,
            "service_account",
            "--actor",
            "*****@*****.**",
            "create",
            "*****@*****.**",
            "other-group",
            "foo",
            "another test",
        )
    service_account = ServiceAccount.get(setup.session,
                                         name="*****@*****.**")
    assert service_account is not None
    assert service_account.machine_set == "foo +bar -(org)"
    assert service_account.description == "this is a service account.\n\n it is for testing"
    group = Group.get(setup.session, name="some-group")
    assert group
    assert get_service_accounts(setup.session, group) == [service_account]
Exemple #16
0
    def post(self, group_id=None, name=None, account_id=None, accountname=None, mapping_id=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()
        service_account = ServiceAccount.get(self.session, account_id, accountname)
        if not service_account:
            return self.notfound()

        if not self.check_access(self.session, self.current_user, service_account):
            return self.forbidden()

        mapping = ServiceAccountPermissionMap.get(self.session, mapping_id)
        if not mapping:
            return self.notfound()

        permission = mapping.permission
        argument = mapping.argument

        mapping.delete(self.session)
        Counter.incr(self.session, "updates")
        self.session.commit()

        AuditLog.log(self.session, self.current_user.id, "revoke_permission",
                     "Revoked permission with argument: {}".format(argument),
                     on_permission_id=permission.id, on_group_id=group.id,
                     on_user_id=service_account.user.id)

        return self.redirect("/groups/{}/service/{}?refresh=yes".format(
            group.name, service_account.user.username))
Exemple #17
0
def get_auditors_group(settings, session):
    # type: (Settings, Session) -> Group
    """Retrieve the group for auditors

    Arg(s):
        settings (settings): settings, to get the `auditors_group` name
        session (session): database session

    Return:
        Group object for the group for Grouper auditors, whose name is
        specified with `auditors_group` settings.

    Raise:
        Raise NoSuchGroup exception if either the name for the
        auditors group is not configured, or the group does not exist
        in the database. Raise GroupDoesNotHaveAuditPermission if the group
        does not actually have the PERMISSION_AUDITOR permission.
    """
    # TODO: switch to exc.NoSuchGroup to remove one source dependency
    # on graph.py
    group_name = get_auditors_group_name(settings)
    if not group_name:
        raise NoSuchGroup("Please ask your admin to configure the `auditors_group` settings")
    group = Group.get(session, name=group_name)
    if not group:
        raise NoSuchGroup("Please ask your admin to configure the default group for auditors")
    if not any([p.name == PERMISSION_AUDITOR for p in group.my_permissions()]):
        raise GroupDoesNotHaveAuditPermission()
    return group
Exemple #18
0
def test_success(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.grant_permission_to_group(USER_ADMIN, "", "admins")
        setup.add_user_to_group("*****@*****.**", "admins")
        setup.create_user("*****@*****.**")
        setup.create_group("some-group")
    mock_ui = MagicMock()
    usecase = setup.usecase_factory.create_convert_user_to_service_account_usecase(
        "*****@*****.**", mock_ui)
    usecase.convert_user_to_service_account("*****@*****.**", "some-group")
    assert mock_ui.mock_calls == [
        call.converted_user_to_service_account("*****@*****.**", "some-group")
    ]

    # Check the User after the conversion
    service_account_user = User.get(setup.session, name="*****@*****.**")
    assert service_account_user
    assert service_account_user.is_service_account
    assert service_account_user.enabled

    # Check the ServiceAccount that should have been created
    service_account = ServiceAccount.get(setup.session, name="*****@*****.**")
    assert service_account
    assert service_account.description == ""
    assert service_account.machine_set == ""
    assert service_account.user_id == service_account_user.id

    # Check that the ServiceAccount is owned by the correct Group
    group = Group.get(setup.session, name="some-group")
    group_service_account = GroupServiceAccount.get(
        setup.session, service_account_id=service_account.id)
    assert group
    assert group_service_account
    assert group_service_account.group_id == group.id
    def post(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        if "@" not in self.request.arguments["name"][0]:
            self.request.arguments["name"][
                0] += "@" + settings.service_account_email_domain

        if not can_create_service_account(self.session, self.current_user,
                                          group):
            return self.forbidden()

        form = ServiceAccountCreateForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "service-account-create.html",
                form=form,
                group=group,
                alerts=self.get_form_alerts(form.errors),
            )

        if form.data["name"].split(
                "@")[-1] != settings.service_account_email_domain:
            form.name.errors.append(
                "All service accounts must have a username ending in {}".
                format(settings.service_account_email_domain))
            return self.render(
                "service-account-create.html",
                form=form,
                group=group,
                alerts=self.get_form_alerts(form.errors),
            )

        try:
            create_service_account(
                self.session,
                self.current_user,
                form.data["name"],
                form.data["description"],
                form.data["machine_set"],
                group,
            )
        except DuplicateServiceAccount:
            form.name.errors.append(
                "A user with name {} already exists".format(form.data["name"]))
        except BadMachineSet as e:
            form.machine_set.errors.append(str(e))

        if form.name.errors or form.machine_set.errors:
            return self.render(
                "service-account-create.html",
                form=form,
                group=group,
                alerts=self.get_form_alerts(form.errors),
            )

        url = "/groups/{}/service/{}?refresh=yes".format(
            group.name, form.data["name"])
        return self.redirect(url)
Exemple #20
0
    def get(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        group_id = kwargs.get("group_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        # Only members can request permissions
        if not self.current_user.is_member(group.my_members()):
            return self.forbidden()

        args_by_perm = get_grantable_permissions(
            self.session,
            settings().restricted_ownership_permissions)
        dropdown_form, text_form = GroupPermissionRequest._get_forms(
            args_by_perm, None)

        self.render(
            "group-permission-request.html",
            dropdown_form=dropdown_form,
            text_form=text_form,
            group=group,
            args_by_perm_json=json.dumps(args_by_perm),
            dropdown_help=settings().permission_request_dropdown_help,
            text_help=settings().permission_request_text_help,
        )
Exemple #21
0
 def add_group_to_group(self, member, group):
     # type: (str, str) -> None
     self.create_group(member)
     self.create_group(group)
     member_obj = Group.get(self.session, name=member)
     assert member_obj
     group_obj = Group.get(self.session, name=group)
     assert group_obj
     edge = GroupEdge(
         group_id=group_obj.id,
         member_type=OBJ_TYPES["Group"],
         member_pk=member_obj.id,
         active=True,
         _role=GROUP_EDGE_ROLES.index("member"),
     )
     edge.add(self.session)
Exemple #22
0
 def create_group(self, name):
     # type: (str) -> None
     """Create a group, does nothing if it already exists."""
     if Group.get(self.session, name=name):
         return
     group = Group(groupname=name)
     group.add(self.session)
    def post(self, user_id=None, name=None):
        service_account = ServiceAccount.get(self.session, user_id, name)
        if not service_account:
            return self.notfound()

        if not self.check_access(self.session, self.current_user, service_account):
            return self.forbidden()

        form = self.get_form()
        if not form.validate():
            return self.render(
                "service-account-enable.html",
                form=form,
                user=service_account.user,
                alerts=self.get_form_alerts(form.errors),
            )

        owner = Group.get(self.session, name=form.data["owner"])
        if owner is None:
            form.owner.errors.append("Group not found.")
            return self.render(
                "service-account-enable.html",
                form=form,
                user=service_account.user,
                alerts=self.get_form_alerts(form.errors),
            )

        enable_service_account(self.session, self.current_user, service_account, owner)
        return self.redirect(
            "/groups/{}/service/{}?refresh=yes".format(owner.name, service_account.user.username)
        )
    def post(self, group_id=None, name=None, account_id=None, accountname=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()
        service_account = ServiceAccount.get(self.session, account_id, accountname)
        if not service_account:
            return self.notfound()

        if not can_manage_service_account(self.session, service_account, self.current_user):
            return self.forbidden()

        form = ServiceAccountEditForm(self.request.arguments, obj=service_account)
        if not form.validate():
            return self.render(
                "service-account-edit.html", service_account=service_account, group=group,
                form=form, alerts=self.get_form_alerts(form.errors)
            )

        try:
            edit_service_account(self.session, self.current_user, service_account,
                                 form.data["description"], form.data["machine_set"])
        except BadMachineSet as e:
            form.machine_set.errors.append(str(e))
            return self.render(
                "service-account-edit.html", service_account=service_account, group=group,
                form=form, alerts=self.get_form_alerts(form.errors)
            )

        return self.redirect("/groups/{}/service/{}".format(
            group.name, service_account.user.username))
    def get(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        group_id = kwargs.get("group_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        # Only members can request permissions
        if not self.current_user.is_member(group.my_members()):
            return self.forbidden()

        args_by_perm = get_grantable_permissions(
            self.session, settings().restricted_ownership_permissions
        )
        dropdown_form, text_form = GroupPermissionRequest._get_forms(args_by_perm, None)

        self.render(
            "group-permission-request.html",
            dropdown_form=dropdown_form,
            text_form=text_form,
            group=group,
            args_by_perm_json=json.dumps(args_by_perm),
            dropdown_help=settings().permission_request_dropdown_help,
            text_help=settings().permission_request_text_help,
        )
Exemple #26
0
    def get(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        status = self.get_argument("status", None)
        offset = int(self.get_argument("offset", 0))
        limit = int(self.get_argument("limit", 100))
        if limit > 9000:
            limit = 9000

        requests = get_requests_by_group(self.session, group, status=status).order_by(
            Request.requested_at.desc()
        )
        members = group.my_members()

        total = requests.count()
        requests = requests.offset(offset).limit(limit)

        current_user_role = {
            'is_owner': user_role_index(self.current_user, members) in OWNER_ROLE_INDICES,
            'is_approver': user_role_index(self.current_user, members) in APPROVER_ROLE_INDICES,
            'is_manager': user_role(self.current_user, members) == "manager",
            'role': user_role(self.current_user, members),
             }

        self.render(
            "group-requests.html", group=group, requests=requests,
            members=members, status=status, statuses=REQUEST_STATUS_CHOICES,
            offset=offset, limit=limit, total=total, current_user_role=current_user_role,
        )
def test_permission_exclude_inactive(session, standard_graph):
    """Ensure disabled groups are excluded from permission data."""
    group = Group.get(session, name="team-sre")
    permission = Permission.get(session, name="ssh")
    assert "team-sre" in [g[0] for g in get_groups_by_permission(session, permission)]
    group.disable()
    assert "team-sre" not in [g[0] for g in get_groups_by_permission(session, permission)]
Exemple #28
0
    def get(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        group_id = kwargs.get("group_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        group = Group.get(self.session, group_id, name)
        if not group or not group.enabled:
            return self.notfound()

        group_md = self.graph.get_group_details(group.name)

        members = group.my_members()
        member_groups = {g for t, g in members if t == "Group"}
        user_is_member = self._is_user_a_member(group, members)

        form = GroupJoinForm()
        form.member.choices = self._get_choices(group, member_groups,
                                                user_is_member)
        return self.render(
            "group-join.html",
            form=form,
            group=group,
            audited=group_md["audited"],
            user_is_member=user_is_member,
        )
    def post(self, group_id=None, name=None, account_id=None, accountname=None, mapping_id=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()
        service_account = ServiceAccount.get(self.session, account_id, accountname)
        if not service_account:
            return self.notfound()

        if not self.check_access(self.session, self.current_user, service_account):
            return self.forbidden()

        mapping = ServiceAccountPermissionMap.get(self.session, mapping_id)
        if not mapping:
            return self.notfound()

        permission = mapping.permission
        argument = mapping.argument

        mapping.delete(self.session)
        Counter.incr(self.session, "updates")
        self.session.commit()

        AuditLog.log(
            self.session,
            self.current_user.id,
            "revoke_permission",
            "Revoked permission with argument: {}".format(argument),
            on_permission_id=permission.id,
            on_group_id=group.id,
            on_user_id=service_account.user.id,
        )

        return self.redirect(
            "/groups/{}/service/{}?refresh=yes".format(group.name, service_account.user.username)
        )
Exemple #30
0
    def post(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        if not user_can_manage_group(self.session, group, self.current_user):
            return self.forbidden()

        form = GroupRemoveForm(self.request.arguments)
        if not form.validate():
            return self.send_error(status_code=400)

        member_type, member_name = form.data["member_type"], form.data[
            "member"]

        members = group.my_members()
        if not members.get((member_type.capitalize(), member_name), None):
            return self.notfound()

        removed_member = get_user_or_group(self.session,
                                           member_name,
                                           user_or_group=member_type)

        if self.current_user == removed_member:
            return self.send_error(
                status_code=400,
                reason="Can't remove yourself. Leave group instead.")

        role_user = is_role_user(self.session, group=group)

        if (role_user and get_role_user(self.session, group=group).user.name
                == removed_member.name):
            return self.send_error(
                status_code=400,
                reason=
                "Can't remove a service account user from the service account group."
            )

        try:
            group.revoke_member(self.current_user, removed_member,
                                "Removed by owner/np-owner/manager")

            AuditLog.log(self.session,
                         self.current_user.id,
                         'remove_from_group',
                         '{} was removed from the group.'.format(
                             removed_member.name),
                         on_group_id=group.id,
                         on_user_id=removed_member.id)
        except PluginRejectedGroupMembershipUpdate as e:
            alert = Alert("danger", str(e))

            if role_user:
                return self.redirect("/service/{}".format(group.name),
                                     alerts=[alert])
            else:
                return self.redirect("/groups/{}".format(group.name),
                                     alerts=[alert])

        return self.redirect("/groups/{}?refresh=yes".format(group.name))
Exemple #31
0
    def post(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

        group = Group.get(self.session, name=name)
        if not group:
            return self.notfound()

        members = group.my_members()
        if not user_role(self.current_user, members) in ("owner", "np-owner"):
            return self.forbidden()

        # Enabling and disabling service accounts via the group endpoints is forbidden
        # because we need the preserve_membership data that is only available via the
        # UserEnable form.
        if is_role_user(self.session, group=group):
            return self.forbidden()

        group.enable()

        self.session.commit()

        AuditLog.log(
            self.session,
            self.current_user.id,
            "enable_group",
            "Enabled group.",
            on_group_id=group.id,
        )

        return self.redirect("/groups/{}?refresh=yes".format(group.name))
    def get(self, request_id, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        members = group.my_members()
        my_role = user_role(self.current_user, members)
        if my_role not in ("manager", "owner", "np-owner"):
            return self.forbidden()

        request = self.session.query(Request).filter_by(id=request_id).scalar()
        if not request:
            return self.notfound()

        on_behalf = get_on_behalf_by_request(self.session, request)

        form = GroupRequestModifyForm(self.request.arguments)
        form.status.choices = self._get_choices(request.status)

        updates = request.my_status_updates()

        self.render("group-request-update.html",
                    group=group,
                    request=request,
                    on_behalf=on_behalf,
                    members=members,
                    form=form,
                    statuses=REQUEST_STATUS_CHOICES,
                    updates=updates)
Exemple #33
0
def get_auditors_group(settings, session):
    """Retrieve the group for auditors

    Arg(s):
        settings (settings): settings, to get the `auditors_group` name
        session (session): database session

    Return:
        Group object for the group for Grouper auditors, whose name is
        specified with `auditors_group` settings.

    Raise:
        Raise NoSuchGroup exception if either the name for the
        auditors group is not configured, or the group does not exist
        in the database. Raise GroupDoesNotHaveAuditPermission if the group
        does not actually have the PERMISSION_AUDITOR permission.
    """
    # TODO: switch to exc.NoSuchGroup to remove one source dependency
    # on graph.py
    group_name = get_auditors_group_name(settings)
    if not group_name:
        raise NoSuchGroup("Please ask your admin to configure the `auditors_group` settings")
    group = Group.get(session, name=group_name)
    if not group:
        raise NoSuchGroup("Please ask your admin to configure the default group for auditors")
    if not any([p.name == PERMISSION_AUDITOR for p in group.my_permissions()]):
        raise GroupDoesNotHaveAuditPermission()
    return group
Exemple #34
0
def test_disabling_group_clears_audit(tmpdir: LocalPath, setup: SetupTest,
                                      browser: Chrome) -> None:
    future = datetime.utcnow() + timedelta(days=60)

    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group", role="owner")
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.create_permission("some-permission", audited=True)
        setup.grant_permission_to_group("some-permission", "argument",
                                        "some-group")
        setup.add_user_to_group("*****@*****.**", "auditors")
        setup.grant_permission_to_group(AUDIT_VIEWER, "", "auditors")
        setup.grant_permission_to_group(AUDIT_MANAGER, "", "auditors")
        setup.grant_permission_to_group(PERMISSION_AUDITOR, "", "auditors")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/audits/create"))

        create_page = AuditsCreatePage(browser)
        create_page.set_end_date(future.strftime("%m/%d/%Y"))
        create_page.submit()

        browser.get(url(frontend_url, "/groups/some-group"))

        group_page = GroupViewPage(browser)
        assert group_page.subheading == "some-group AUDIT IN PROGRESS"

    # Check that this created email reminder messages to the group owner.  We have to refresh the
    # session since otherwise SQLite may not see changes.
    setup.reopen_database()
    group = Group.get(setup.session, name="some-group")
    assert group
    expected_key = f"audit-{group.id}"
    emails = setup.session.query(AsyncNotification).filter_by(
        sent=False, email="*****@*****.**").all()
    assert len(emails) > 0
    assert all((e.key is None or e.key == expected_key for e in emails))
    assert all(("Group Audit" in e.subject for e in emails))

    # Now, disable the group, which should complete the audit.
    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups/some-group"))
        page = GroupViewPage(browser)

        audit_modal = page.get_audit_modal()
        audit_modal.click_close_button()
        page.wait_until_audit_modal_clears()
        page.click_disable_button()
        modal = page.get_disable_modal()
        modal.confirm()

        assert page.subheading == "some-group (disabled)"

    # And now all of the email messages should be marked sent except the immediate one (the one
    # that wasn't created with async_send_email).
    setup.reopen_database()
    emails = setup.session.query(AsyncNotification).filter_by(
        sent=False, email="*****@*****.**").all()
    assert len(emails) == 1
    assert emails[0].key is None
Exemple #35
0
def test_success(setup):
    # type: (SetupTest) -> None
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group")

    mock_ui = MagicMock()
    usecase = setup.usecase_factory.create_create_service_account_usecase("*****@*****.**", mock_ui)
    usecase.create_service_account(
        "*****@*****.**", "some-group", "machine-set", "description"
    )
    assert mock_ui.mock_calls == [
        call.created_service_account("*****@*****.**", "some-group")
    ]

    # Check the User and ServiceAccount that were created.
    user = User.get(setup.session, name="*****@*****.**")
    assert user is not None
    assert user.is_service_account
    assert user.enabled
    service = ServiceAccount.get(setup.session, name="*****@*****.**")
    assert service is not None
    assert service.machine_set == "machine-set"
    assert service.description == "description"

    # Check that the ServiceAccount is owned by the correct Group.
    group = Group.get(setup.session, name="some-group")
    assert group is not None
    linkage = GroupServiceAccount.get(setup.session, service_account_id=service.id)
    assert linkage is not None
    assert linkage.group_id == group.id
Exemple #36
0
    def post(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        members = group.my_members()
        if not user_role(self.current_user, members) in ("owner", "np-owner"):
            return self.forbidden()

        # Enabling and disabling service accounts via the group endpoints is forbidden
        # because we need the preserve_membership data that is only available via the
        # UserEnable form.
        if is_role_user(self.session, group=group):
            return self.forbidden()

        group.disable()

        self.session.commit()

        AuditLog.log(self.session, self.current_user.id, 'disable_group',
                     'Disabled group.', on_group_id=group.id)

        if group.audit:
            # complete the audit
            group.audit.complete = True
            self.session.commit()

            AuditLog.log(self.session, self.current_user.id, 'complete_audit',
                         'Disabling group completes group audit.', on_group_id=group.id)

        return self.redirect("/groups/{}?refresh=yes".format(group.name))
Exemple #37
0
def get_role_user(session, user=None, group=None):
    # type: (Session, User, Group) -> RoleUser
    """
    Takes in a User or a Group and returns a dictionary that contains
    all of the service account components for the service account that
    the user/group is part of.

    Args:
        session: the database session
        user: a User object to check
        group: a Group object to check

    Throws:
        RoleUserNotFound: if the user or group is not part of a service account

    Returns:
        a dictionary with all components of the service account of the
            user or group passed in
    """
    if not is_role_user(session, user, group):
        raise RoleUserNotFound()

    if user:
        name = user.name
    else:
        assert group is not None
        name = group.name
    user_obj = User.get(session, name=name)
    assert user_obj, "User object for role user not found"
    group_obj = Group.get(session, name=name)
    assert group_obj, "Group object for role user not found"
    return RoleUser(user_obj, group_obj)
    def get(self, request_id, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        members = group.my_members()
        my_role = user_role(self.current_user, members)
        if my_role not in ("manager", "owner", "np-owner"):
            return self.forbidden()

        request = self.session.query(Request).filter_by(id=request_id).scalar()
        if not request:
            return self.notfound()

        on_behalf = get_on_behalf_by_request(self.session, request)

        form = GroupRequestModifyForm(self.request.arguments)
        form.status.choices = self._get_choices(request.status)

        updates = request.my_status_updates()

        self.render(
            "group-request-update.html", group=group, request=request, on_behalf=on_behalf,
            members=members, form=form, statuses=REQUEST_STATUS_CHOICES, updates=updates
        )
Exemple #39
0
def get_role_user(session, user=None, group=None):
    # type: (Session, User, Group) -> RoleUser
    """
    Takes in a User or a Group and returns a dictionary that contains
    all of the service account components for the service account that
    the user/group is part of.

    Args:
        session: the database session
        user: a User object to check
        group: a Group object to check

    Throws:
        RoleUserNotFound: if the user or group is not part of a service account

    Returns:
        a dictionary with all components of the service account of the
            user or group passed in
    """
    if not is_role_user(session, user, group):
        raise RoleUserNotFound()

    if user:
        name = user.name
    else:
        assert group is not None
        name = group.name
    return RoleUser(User.get(session, name=name), Group.get(session, name=name))
    def post(self, user_id=None, name=None):
        service_account = ServiceAccount.get(self.session, user_id, name)
        if not service_account:
            return self.notfound()

        if not self.check_access(self.session, self.current_user,
                                 service_account):
            return self.forbidden()

        form = self.get_form()
        if not form.validate():
            return self.render("service-account-enable.html",
                               form=form,
                               user=service_account.user,
                               alerts=self.get_form_alerts(form.errors))

        owner = Group.get(self.session, name=form.data["owner"])
        if owner is None:
            form.owner.errors.append("Group not found.")
            return self.render("service-account-enable.html",
                               form=form,
                               user=service_account.user,
                               alerts=self.get_form_alerts(form.errors))

        enable_service_account(self.session, self.current_user,
                               service_account, owner)
        return self.redirect("/groups/{}/service/{}?refresh=yes".format(
            owner.name, service_account.user.username))
Exemple #41
0
    def get(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        status = self.get_argument("status", None)
        offset = int(self.get_argument("offset", 0))
        limit = int(self.get_argument("limit", 100))
        if limit > 9000:
            limit = 9000

        requests = group.my_requests(status).order_by(
            Request.requested_at.desc()
        )
        members = group.my_members()

        total = requests.count()
        requests = requests.offset(offset).limit(limit)

        current_user_role = {
            'is_owner': user_role_index(self.current_user, members) in OWNER_ROLE_INDICES,
            'is_approver': user_role_index(self.current_user, members) in APPROVER_ROLE_INDICES,
            'is_manager': user_role(self.current_user, members) == "manager",
            'role': user_role(self.current_user, members),
             }

        self.render(
            "group-requests.html", group=group, requests=requests,
            members=members, status=status, statuses=REQUEST_STATUS_CHOICES,
            offset=offset, limit=limit, total=total, current_user_role=current_user_role,
        )
def test_group_disable_group_owner(user_make_session, group_make_session, get_plugin_proxy, session,
                                   users, groups):
    group_make_session.return_value = session
    user_make_session.return_value = session
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

    username = '******'
    groupname = 'team-sre'

    # add
    call_main('group', 'add_member', '--owner', groupname, username)
    assert (u'User', username) in Group.get(session, name=groupname).my_members()

    # disable (fails)
    call_main('user', 'disable', username)
    assert (u'User', username) in Group.get(session, name=groupname).my_members()
Exemple #43
0
    def get(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")
        accountname = self.get_path_argument("accountname")

        self.handle_refresh()
        group = Group.get(self.session, name=name)
        if not group:
            return self.notfound()
        service_account = ServiceAccount.get(self.session, name=accountname)
        if not service_account:
            return self.notfound()

        # We don't need the group to be valid to find the service account, but ensure that the
        # group is the owner of the service account so that we don't generate confusing URLs and
        # broken information on the view page.
        if service_account.owner.group_id != group.id:
            return self.notfound()

        user = service_account.user
        self.render(
            "service-account.html",
            service_account=service_account,
            group=group,
            user=user,
            **get_user_view_template_vars(self.session, self.current_user, user, self.graph)
        )
Exemple #44
0
def service_account_command(args, settings, session_factory):
    # type: (Namespace, CtlSettings, SessionFactory) -> None
    session = session_factory.create_session()
    actor_user = User.get(session, name=args.actor_name)
    if not actor_user:
        logging.fatal('Actor user "{}" is not a valid Grouper user'.format(
            args.actor_name))
        return

    if args.subcommand == "create":
        name = args.name
        if ServiceAccount.get(session, name=name):
            logging.info("{}: Already exists. Doing nothing.".format(name))
            return
        owner_group = Group.get(session, name=args.owner_group)
        if not owner_group:
            logging.fatal('Owner group "{}" does not exist.'.format(
                args.owner_group))
            return
        logging.info("{}: No such service account, creating...".format(name))
        description = args.description
        machine_set = args.machine_set
        create_service_account(session, actor_user, name, description,
                               machine_set, owner_group)
        return
Exemple #45
0
def test_create_as_service_account(setup):
    """Test that a service account can create another service account."""
    with setup.transaction():
        setup.create_group("some-group")
        setup.create_service_account("*****@*****.**", "another-group")
        setup.grant_permission_to_service_account(USER_ADMIN, "", "*****@*****.**")

    run_ctl(
        setup,
        "service_account",
        "--actor",
        "*****@*****.**",
        "create",
        "*****@*****.**",
        "some-group",
        "foo +bar -(org)",
        "this is a service account.\n\n it is for testing",
    )
    service_account = ServiceAccount.get(setup.session, name="*****@*****.**")
    assert service_account is not None
    assert service_account.user.name == "*****@*****.**"
    assert service_account.machine_set == "foo +bar -(org)"
    assert service_account.description == "this is a service account.\n\n it is for testing"
    group = Group.get(setup.session, name="some-group")
    assert get_service_accounts(setup.session, group) == [service_account]
Exemple #46
0
    def create_service_account(self,
                               name,
                               owner,
                               machine_set,
                               description,
                               initial_metadata=None):
        # type: (str, str, str, str, Optional[Dict[str,str]]) -> None
        group = Group.get(self.session, name=owner)
        if not group:
            raise GroupNotFoundException(owner)

        # Create the service account in the database.
        user = SQLUser(username=name, is_service_account=True)
        service = SQLServiceAccount(user=user,
                                    machine_set=machine_set,
                                    description=description)
        user.add(self.session)
        service.add(self.session)

        # Flush the account to allocate an ID.
        self.session.flush()

        # Set initial user metadata fields if present.
        if initial_metadata is not None:
            for key, value in initial_metadata.items():
                # TODO: move this to use the hexagonal architecture model.
                set_user_metadata(self.session, user.id, key, value)

        # Create the linkage to the owner.
        GroupServiceAccount(group_id=group.id,
                            service_account=service).add(self.session)
def test_oneoff(mock_make_session, mock_load_plugins, session):
    mock_make_session.return_value = session
    username = '******'
    other_username = '******'
    groupname = 'fake_group'

    class FakeOneOff(object):
        def configure(self, service_name):
            pass

        def run(self, session, **kwargs):
            if kwargs.get('group'):
                Group.get_or_create(session, groupname=groupname)
                session.commit()
            elif kwargs.get('key') == 'valuewith=':
                User.get_or_create(session, username=other_username)
                session.commit()
            else:
                User.get_or_create(session, username=username)
                session.commit()

    mock_load_plugins.return_value = [FakeOneOff()]

    # dry_run
    call_main('oneoff', 'run', 'FakeOneOff')
    assert User.get(session, name=username) is None, 'default dry_run means no writes'
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is None, '"group" not in arg so no group created'

    # not dry_run, create a user
    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff')
    assert User.get(session, name=username) is not None, 'dry_run off means writes'
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is None, '"group" not in arg so no group created'

    # not dry_run, use kwarg to create a group
    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'group=1')
    assert User.get(session, name=username) is not None, 'dry_run off means writes'
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is not None, '"group" in arg so group created'

    # invalid format for argument should result in premature system exit
    with pytest.raises(SystemExit):
        call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'bad_arg')

    call_main('oneoff', 'run', '--no-dry_run', 'FakeOneOff', 'key=valuewith=')
    assert User.get(session, name=other_username) is not None, '"valuewith= in arg, create user2'
def test_add_role_user(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    create_role_user(session, user, '*****@*****.**', 'Hi', 'canjoin')

    u = User.get(session, name="*****@*****.**")
    g = Group.get(session, name="*****@*****.**")

    assert u is not None
    assert g is not None
    assert is_role_user(session, user=u)
    assert is_role_user(session, group=g)
    assert get_role_user(session, user=u).group.id == g.id
    assert get_role_user(session, group=g).user.id == u.id
    assert not is_role_user(session, user=user)
    assert not is_role_user(session, group=Group.get(session, name="team-sre"))
def test_group_add_remove_member(make_session, session, users, groups):
    make_session.return_value = session

    username = '******'
    groupname = 'team-sre'

    # add
    assert (u'User', username) not in groups[groupname].my_members()
    call_main('group', 'add_member', '--member', groupname, username)
    all_members = Group.get(session, name=groupname).my_members()
    assert (u'User', username) in all_members
    _, _, _, role, _, _ = all_members[(u'User', username)]
    assert GROUP_EDGE_ROLES[role] == "member"

    # remove
    call_main('group', 'remove_member', groupname, username)
    assert (u'User', username) not in Group.get(session, name=groupname).my_members()
Exemple #50
0
def test_add_role_user(session, users, http_client, base_url):  # noqa: F811
    user = users["*****@*****.**"]

    # Add account
    create_role_user(session, user, "*****@*****.**", "Hi", "canjoin")

    u = User.get(session, name="*****@*****.**")
    g = Group.get(session, name="*****@*****.**")

    assert u is not None
    assert g is not None
    assert is_role_user(session, user=u)
    assert is_role_user(session, group=g)
    assert get_role_user(session, user=u).group.id == g.id
    assert get_role_user(session, group=g).user.id == u.id
    assert not is_role_user(session, user=user)
    assert not is_role_user(session, group=Group.get(session, name="team-sre"))
Exemple #51
0
def test_oneoff(mock_load_plugins, session, tmpdir):  # noqa: F811
    username = "******"
    other_username = "******"
    groupname = "fake_group"

    class FakeOneOff(object):
        def configure(self, service_name):
            pass

        def run(self, session, **kwargs):
            if kwargs.get("group"):
                Group.get_or_create(session, groupname=groupname)
                session.commit()
            elif kwargs.get("key") == "valuewith=":
                User.get_or_create(session, username=other_username)
                session.commit()
            else:
                User.get_or_create(session, username=username)
                session.commit()

    mock_load_plugins.return_value = [FakeOneOff()]

    # dry_run
    call_main(session, tmpdir, "oneoff", "run", "FakeOneOff")
    assert User.get(session, name=username) is None, "default dry_run means no writes"
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is None, '"group" not in arg so no group created'

    # not dry_run, create a user
    call_main(session, tmpdir, "oneoff", "run", "--no-dry_run", "FakeOneOff")
    assert User.get(session, name=username) is not None, "dry_run off means writes"
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is None, '"group" not in arg so no group created'

    # not dry_run, use kwarg to create a group
    call_main(session, tmpdir, "oneoff", "run", "--no-dry_run", "FakeOneOff", "group=1")
    assert User.get(session, name=username) is not None, "dry_run off means writes"
    assert User.get(session, name=other_username) is None, '"valuewith= not in arg'
    assert Group.get(session, name=groupname) is not None, '"group" in arg so group created'

    # invalid format for argument should result in premature system exit
    with pytest.raises(SystemExit):
        call_main(session, tmpdir, "oneoff", "run", "--no-dry_run", "FakeOneOff", "bad_arg")

    call_main(session, tmpdir, "oneoff", "run", "--no-dry_run", "FakeOneOff", "key=valuewith=")
    assert User.get(session, name=other_username) is not None, '"valuewith= in arg, create user2'
Exemple #52
0
 def add_group_to_group(self, member, group, expiration=None):
     # type: (str, str, Optional[datetime]) -> None
     self.create_group(member)
     self.create_group(group)
     member_obj = Group.get(self.session, name=member)
     assert member_obj
     group_obj = Group.get(self.session, name=group)
     assert group_obj
     edge = GroupEdge(
         group_id=group_obj.id,
         member_type=OBJ_TYPES["Group"],
         member_pk=member_obj.id,
         expiration=expiration,
         active=True,
         _role=GROUP_EDGE_ROLES.index("member"),
     )
     edge.add(self.session)
Exemple #53
0
def test_group_add_remove_owner(get_plugin_proxy, session, tmpdir, users, groups):  # noqa: F811
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

    username = "******"
    groupname = "team-sre"

    # add
    assert (u"User", username) not in groups[groupname].my_members()
    call_main(session, tmpdir, "group", "add_member", "--owner", groupname, username)
    all_members = Group.get(session, name=groupname).my_members()
    assert (u"User", username) in all_members
    _, _, _, role, _, _ = all_members[(u"User", username)]
    assert GROUP_EDGE_ROLES[role] == "owner"

    # remove (fails)
    call_main(session, tmpdir, "group", "remove_member", groupname, username)
    assert (u"User", username) in Group.get(session, name=groupname).my_members()
def test_grant_and_revoke(session, standard_graph, graph, groups, permissions,
        http_client, base_url):
    """Test that permission grant and revokes are reflected correctly."""
    group_name = "team-sre"
    permission_name = "sudo"
    user_name = "*****@*****.**"

    def _check_graph_for_perm(graph):
        return any(map(lambda x: x.permission == permission_name,
                graph.permission_metadata[group_name]))

    # make some permission admins
    perm_admin, _ = Permission.get_or_create(session, name=PERMISSION_ADMIN, description="")
    session.commit()
    grant_permission(groups["security-team"], perm_admin)

    # grant attempt by non-permission admin
    fe_url = url(base_url, "/permissions/grant/{}".format(group_name))
    with pytest.raises(HTTPError):
        yield http_client.fetch(fe_url, method="POST",
                body=urlencode({"permission": permission_name, "argument": "specific_arg"}),
                headers={'X-Grouper-User': "******"})

    graph.update_from_db(session)
    assert not _check_graph_for_perm(graph), "no permissions granted"

    # grant by permission admin
    resp = yield http_client.fetch(fe_url, method="POST",
            body=urlencode({"permission": permission_name, "argument": "specific_arg"}),
            headers={'X-Grouper-User': user_name})
    assert resp.code == 200

    graph.update_from_db(session)
    assert _check_graph_for_perm(graph), "permissions granted, successfully"

    # figure out mapping_id of grant
    permission_id = Permission.get(session, name=permission_name).id
    group_id = Group.get(session, name=group_name).id
    mapping = session.query(PermissionMap).filter(
            PermissionMap.permission_id == permission_id,
            PermissionMap.group_id == group_id).first()

    # revoke permission by non-admin
    fe_url = url(base_url, "/permissions/{}/revoke/{}".format(permission_name, mapping.id))
    with pytest.raises(HTTPError):
        yield http_client.fetch(fe_url, method="POST", body=urlencode({}),
                headers={'X-Grouper-User': "******"})

    graph.update_from_db(session)
    assert _check_graph_for_perm(graph), "permissions not revoked"

    # revoke permission for realz
    resp = yield http_client.fetch(fe_url, method="POST", body=urlencode({}),
            headers={'X-Grouper-User': user_name})
    assert resp.code == 200

    graph.update_from_db(session)
    assert not _check_graph_for_perm(graph), "permissions revoked successfully"
def test_group_add_remove_owner(make_session, get_plugin_proxy, session, users, groups):
    make_session.return_value = session
    get_plugin_proxy.return_value = PluginProxy([GroupOwnershipPolicyPlugin()])

    username = '******'
    groupname = 'team-sre'

    # add
    assert (u'User', username) not in groups[groupname].my_members()
    call_main('group', 'add_member', '--owner', groupname, username)
    all_members = Group.get(session, name=groupname).my_members()
    assert (u'User', username) in all_members
    _, _, _, role, _, _ = all_members[(u'User', username)]
    assert GROUP_EDGE_ROLES[role] == "owner"

    # remove (fails)
    call_main('group', 'remove_member', groupname, username)
    assert (u'User', username) in Group.get(session, name=groupname).my_members()
Exemple #56
0
    def member(self):
        # TODO(cbguder): get around circular dependencies
        from grouper.models.group import Group

        if self.edge.member_type == 0:  # User
            return User.get(self.session, pk=self.edge.member_pk)
        elif self.edge.member_type == 1:  # Group
            return Group.get(self.session, pk=self.edge.member_pk)
        raise Exception("invalid member_type in AuditMember!")
Exemple #57
0
    def get(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        members = group.my_members()
        if not user_role(self.current_user, members):
            return self.forbidden()

        return self.render("group-leave.html", group=group)