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)
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
Beispiel #3
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))
Beispiel #4
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))
Beispiel #5
0
def test_basic_request(graph, groups, permissions, session, standard_graph,
                       users):  # noqa: F811
    group_sre = groups["team-sre"]
    group_not_sre = [g for name, g in groups.items() if name != "team-sre"]

    assert not any([
        get_requests_by_group(session, group, status="pending").all()
        for group in groups.values() if not is_role_user(session, group=group)
    ]), "no group should start with pending requests"

    group_sre.add_member(users["*****@*****.**"],
                         users["*****@*****.**"],
                         reason="for the lulz")
    session.commit()

    request_not_sre = [
        get_requests_by_group(session, group, status="pending").all()
        for group in group_not_sre
    ]
    assert not any(
        request_not_sre), "only affected group should show pending requests"
    request_sre = get_requests_by_group(session, group_sre,
                                        status="pending").all()
    assert len(request_sre) == 1, "affected group should have request"

    request = session.query(Request).filter_by(id=request_sre[0].id).scalar()
    request.update_status(users["*****@*****.**"], "actioned",
                          "for being a good person")
    session.commit()

    assert not any([
        get_requests_by_group(session, group, status="pending").all()
        for group in groups.values()
    ]), "no group should have requests after being actioned"
Beispiel #6
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))
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_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"))
Beispiel #9
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"))
Beispiel #10
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)
Beispiel #11
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))
Beispiel #12
0
def test_add_role_user(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    fe_url = url(base_url, '/service/create')
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       'name': '*****@*****.**',
                                       "description": "Hi",
                                       "canjoin": "canjoin"
                                   }),
                                   headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    assert User.get(session, name="*****@*****.**") is None
    assert Group.get(session, name="*****@*****.**") is None

    # Add account
    fe_url = url(base_url, '/service/create')
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       'name': '*****@*****.**',
                                       "description": "Hi",
                                       "canjoin": "canjoin"
                                   }),
                                   headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    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"))
Beispiel #13
0
    def get(self, group_id=None, name=None):
        self.handle_refresh()
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        if is_role_user(self.session, group=group):
            return self.redirect("/service/{}".format(group.groupname))

        self.render(
            "group.html", group=group,
            **get_group_view_template_vars(self.session, self.current_user, group, self.graph)
        )
Beispiel #14
0
    def get(self, group_id=None, name=None):
        self.handle_refresh()
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

        if is_role_user(self.session, group=group):
            return self.redirect("/service/{}".format(group.groupname))

        self.render("group.html",
                    group=group,
                    **get_group_view_template_vars(self.session,
                                                   self.current_user, group,
                                                   self.graph))
Beispiel #15
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 = 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))

        if group.groupname != form.data["groupname"] 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))

        group.groupname = form.data["groupname"]
        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")

        try:
            self.session.commit()
        except IntegrityError:
            self.session.rollback()
            form.groupname.errors.append("{} already exists".format(
                form.data["groupname"]))
            return self.render("group-edit.html",
                               group=group,
                               form=form,
                               alerts=self.get_form_alerts(form.errors))

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

        return self.redirect("/groups/{}".format(group.name))
Beispiel #16
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]

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

        if is_role_user(self.session, group=group):
            return self.redirect("/service/{}".format(group.groupname))

        self.render(
            "group.html",
            group=group,
            **get_group_view_template_vars(self.session, self.current_user, group, self.graph)
        )
Beispiel #17
0
 def _get_group_tuples(session, enabled=True):
     '''
     Returns a dict of groupname: GroupTuple.
     '''
     out = {}
     groups = (session.query(Group).order_by(
         Group.groupname)).filter(Group.enabled == enabled)
     for group in groups:
         out[group.groupname] = GroupTuple(id=group.id,
                                           groupname=group.groupname,
                                           name=group.groupname,
                                           description=group.description,
                                           canjoin=group.canjoin,
                                           enabled=group.enabled,
                                           service_account=is_role_user(
                                               session, group=group),
                                           type="Group")
     return out
Beispiel #18
0
    def get(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

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

        if is_role_user(self.session, group=group):
            return self.redirect("/service/{}".format(group.groupname))

        self.render("group.html",
                    group=group,
                    audit_members_infos=get_group_audit_members_infos(
                        self.session, group),
                    **get_group_view_template_vars(self.session,
                                                   self.current_user, group,
                                                   self.graph))
Beispiel #19
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 = 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)
            )

        if group.groupname != form.data["groupname"] 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)
            )

        group.groupname = form.data["groupname"]
        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")

        try:
            self.session.commit()
        except IntegrityError:
            self.session.rollback()
            form.groupname.errors.append("{} already exists".format(form.data["groupname"]))
            return self.render(
                "group-edit.html", group=group, form=form, alerts=self.get_form_alerts(form.errors)
            )

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

        return self.redirect("/groups/{}".format(group.name))
Beispiel #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]

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

        if is_role_user(self.session, group=group):
            return self.redirect("/service/{}".format(group.groupname))

        self.render("group.html",
                    group=group,
                    audit_members_infos=get_group_audit_members_infos(
                        self.session, group),
                    **get_group_view_template_vars(self.session,
                                                   self.current_user, group,
                                                   self.graph))
Beispiel #21
0
 def _get_group_tuples(session, enabled=True):
     '''
     Returns a dict of groupname: GroupTuple.
     '''
     out = {}
     groups = (
         session.query(Group)
         .order_by(Group.groupname)
     ).filter(
         Group.enabled == enabled
     )
     for group in groups:
         out[group.groupname] = GroupTuple(
             id=group.id,
             groupname=group.groupname,
             name=group.groupname,
             description=group.description,
             canjoin=group.canjoin,
             enabled=group.enabled,
             service_account=is_role_user(session, group=group),
             type="Group"
         )
     return out
Beispiel #22
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()

        members = group.my_members()
        my_role = user_role(self.current_user, members)
        form = self.get_form(role=my_role)
        if not form.validate():
            return self.render("group-add.html",
                               form=form,
                               group=group,
                               alerts=self.get_form_alerts(form.errors))

        member = get_user_or_group(self.session, form.data["member"])
        if member.type == "User" and is_role_user(self.session, member):
            # For service accounts, we want to always add the group to other groups, not the user
            member = get_role_user(self.session, user=member).group
        if not member:
            form.member.errors.append("User or group not found.")
        elif (member.type, member.name) in group.my_members():
            form.member.errors.append(
                "User or group is already a member of this group.")
        elif group.name == member.name:
            form.member.errors.append(
                "By definition, this group is a member of itself already.")

        # Ensure this doesn't violate auditing constraints
        fail_message = 'This join is denied with this role at this time.'
        try:
            user_can_join = assert_can_join(group,
                                            member,
                                            role=form.data["role"])
        except UserNotAuditor as e:
            user_can_join = False
            fail_message = e
        if not user_can_join:
            form.member.errors.append(fail_message)

        if form.member.errors:
            return self.render("group-add.html",
                               form=form,
                               group=group,
                               alerts=self.get_form_alerts(form.errors))

        expiration = None
        if form.data["expiration"]:
            expiration = datetime.strptime(form.data["expiration"], "%m/%d/%Y")

        try:
            group.add_member(requester=self.current_user,
                             user_or_group=member,
                             reason=form.data["reason"],
                             status='actioned',
                             expiration=expiration,
                             role=form.data["role"])
        except InvalidRoleForMember as e:
            return self.render("group-add.html",
                               form=form,
                               group=group,
                               alerts=[Alert('danger', e.message)])

        self.session.commit()

        on_user_id = member.id if member.type == "User" else None
        AuditLog.log(self.session,
                     self.current_user.id,
                     'join_group',
                     '{} added to group with role: {}'.format(
                         member.name, form.data["role"]),
                     on_group_id=group.id,
                     on_user_id=on_user_id)

        if member.type == "User":
            send_email(
                self.session, [member.name],
                'Added to group: {}'.format(group.name), 'request_actioned',
                settings, {
                    'group_name': group.name,
                    'actioned_by': self.current_user.name,
                    'reason': form.data['reason'],
                    'expiration': expiration,
                    'role': form.data['role'],
                })

        return self.redirect("/groups/{}?refresh=yes".format(group.name))
Beispiel #23
0
def test_sa_pubkeys(session, users, http_client, base_url):
    user = users['*****@*****.**']

    # Add account
    fe_url = url(base_url, '/service/create')
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       'name': '*****@*****.**',
                                       "description": "Hi",
                                       "canjoin": "canjoin"
                                   }),
                                   headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    assert User.get(session, name="*****@*****.**") is None
    assert Group.get(session, name="*****@*****.**") is None

    # Add account
    fe_url = url(base_url, '/service/create')
    resp = yield http_client.fetch(fe_url,
                                   method="POST",
                                   body=urlencode({
                                       'name': '*****@*****.**',
                                       "description": "Hi",
                                       "canjoin": "canjoin"
                                   }),
                                   headers={'X-Grouper-User': user.username})
    assert resp.code == 200

    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)

    good_key = (
        'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCUQeasspT/etEJR2WUoR+h2sMOQYbJgr0Q'
        'E+J8p97gEhmz107KWZ+3mbOwyIFzfWBcJZCEg9wy5Paj+YxbGONqbpXAhPdVQ2TLgxr41bNXvbcR'
        'AxZC+Q12UZywR4Klb2kungKz4qkcmSZzouaKK12UxzGB3xQ0N+3osKFj3xA1+B6HqrVreU19XdVo'
        'AJh0xLZwhw17/NDM+dAcEdMZ9V89KyjwjraXtOVfFhQF0EDF0ame8d6UkayGrAiXC2He0P2Cja+J'
        '371P27AlNLHFJij8WGxvcGGSeAxMLoVSDOOllLCYH5UieV8mNpX1kNe2LeA58ciZb0AXHaipSmCH'
        'gh/ some-comment')

    bad_key = 'ssh-rsa AAAblahblahkey some-comment'

    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':
                                                       good_key}),
                                       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': good_key}),
                                   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': bad_key}),
                                   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 == good_key

    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)
Beispiel #24
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()

        members = group.my_members()
        my_role = user_role(self.current_user, members)
        form = self.get_form(role=my_role)
        if not form.validate():
            return self.render("group-add.html",
                               form=form,
                               group=group,
                               alerts=self.get_form_alerts(form.errors))

        member = get_user_or_group(self.session, form.data["member"])
        if member.type == "User" and is_role_user(self.session, member):
            # For service accounts, we want to always add the group to other groups, not the user
            member = get_role_user(self.session, user=member).group
        if not member:
            form.member.errors.append("User or group not found.")
        elif (member.type, member.name) in group.my_members():
            form.member.errors.append(
                "User or group is already a member of this group.")
        elif group.name == member.name:
            form.member.errors.append(
                "By definition, this group is a member of itself already.")

        # Ensure this doesn't violate auditing constraints
        try:
            assert_can_join(group, member, role=form.data["role"])
        except UserNotAuditor as e:
            form.member.errors.append(str(e))

        if form.member.errors:
            return self.render("group-add.html",
                               form=form,
                               group=group,
                               alerts=self.get_form_alerts(form.errors))

        expiration = None
        if form.data["expiration"]:
            expiration = datetime.strptime(form.data["expiration"], "%m/%d/%Y")

        try:
            group.add_member(
                requester=self.current_user,
                user_or_group=member,
                reason=form.data["reason"],
                status="actioned",
                expiration=expiration,
                role=form.data["role"],
            )
        except InvalidRoleForMember as e:
            return self.render("group-add.html",
                               form=form,
                               group=group,
                               alerts=[Alert("danger", str(e))])

        self.session.commit()

        on_user_id = member.id if member.type == "User" else None
        AuditLog.log(
            self.session,
            self.current_user.id,
            "join_group",
            "{} added to group with role: {}".format(member.name,
                                                     form.data["role"]),
            on_group_id=group.id,
            on_user_id=on_user_id,
        )

        if member.type == "User":
            send_email(
                self.session,
                [member.name],
                "Added to group: {}".format(group.name),
                "request_actioned",
                settings(),
                {
                    "group_name": group.name,
                    "actioned_by": self.current_user.name,
                    "reason": form.data["reason"],
                    "expiration": expiration,
                    "role": form.data["role"],
                },
            )

        return self.redirect("/groups/{}?refresh=yes".format(group.name))
Beispiel #25
0
def test_sa_tokens(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"))

    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 b"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 b"Disabled token: myDHDToken" in resp.body
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)
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
Beispiel #28
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()

        members = group.my_members()
        my_role = user_role(self.current_user, members)
        form = self.get_form(role=my_role)
        if not form.validate():
            return self.render(
                "group-add.html", form=form, group=group,
                alerts=self.get_form_alerts(form.errors)
            )

        member = get_user_or_group(self.session, form.data["member"])
        if member.type == "User" and is_role_user(self.session, member):
            # For service accounts, we want to always add the group to other groups, not the user
            member = get_role_user(self.session, user=member).group
        if not member:
            form.member.errors.append("User or group not found.")
        elif (member.type, member.name) in group.my_members():
            form.member.errors.append("User or group is already a member of this group.")
        elif group.name == member.name:
            form.member.errors.append("By definition, this group is a member of itself already.")

        # Ensure this doesn't violate auditing constraints
        fail_message = 'This join is denied with this role at this time.'
        try:
            user_can_join = assert_can_join(group, member, role=form.data["role"])
        except UserNotAuditor as e:
            user_can_join = False
            fail_message = e
        if not user_can_join:
            form.member.errors.append(fail_message)

        if form.member.errors:
            return self.render(
                "group-add.html", form=form, group=group,
                alerts=self.get_form_alerts(form.errors)
            )

        expiration = None
        if form.data["expiration"]:
            expiration = datetime.strptime(form.data["expiration"], "%m/%d/%Y")

        try:
            group.add_member(
                requester=self.current_user,
                user_or_group=member,
                reason=form.data["reason"],
                status='actioned',
                expiration=expiration,
                role=form.data["role"]
            )
        except InvalidRoleForMember as e:
            return self.render(
                "group-add.html", form=form, group=group,
                alerts=[
                    Alert('danger', e.message)
                ]
            )

        self.session.commit()

        on_user_id = member.id if member.type == "User" else None
        AuditLog.log(self.session, self.current_user.id, 'join_group',
                     '{} added to group with role: {}'.format(
                         member.name, form.data["role"]),
                     on_group_id=group.id, on_user_id=on_user_id)

        if member.type == "User":
            send_email(
                self.session,
                [member.name],
                'Added to group: {}'.format(group.name),
                'request_actioned',
                settings,
                {
                    'group_name': group.name,
                    'actioned_by': self.current_user.name,
                    'reason': form.data['reason'],
                    'expiration': expiration,
                    'role': form.data['role'],
                }
            )

        return self.redirect("/groups/{}?refresh=yes".format(group.name))
def test_disable_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"))

    disable_role_user(session, user=u)
    u = User.get(session, name="*****@*****.**")
    assert not u.enabled, "The SA User should be disabled"
    g = Group.get(session, name="*****@*****.**")
    assert not g.enabled, "The SA Group should be disabled"

    enable_role_user(session, actor=user, group=g, preserve_membership=True)
    u = User.get(session, name="*****@*****.**")
    assert u.enabled, "The SA User should be enabled"
    g = Group.get(session, name="*****@*****.**")
    assert g.enabled, "The SA Group should be enabled"

    with pytest.raises(HTTPError):
        fe_url = url(base_url,
                     '/groups/{}/disable'.format("*****@*****.**"))
        resp = yield http_client.fetch(
            fe_url,
            method="POST",
            body="",
            headers={'X-Grouper-User': user.username})

    u = User.get(session, name="*****@*****.**")
    assert u.enabled, "Attempting to disable SAs through groups/disable should not work"
    g = Group.get(session, name="*****@*****.**")
    assert g.enabled, "Attempting to disable SAs through groups/disable should not work"

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

    u = User.get(session, name="*****@*****.**")
    assert not u.enabled, "The SA User should be disabled"
    g = Group.get(session, name="*****@*****.**")
    assert not g.enabled, "The SA Group should be disabled"

    with pytest.raises(HTTPError):
        fe_url = url(base_url, '/groups/{}/enable'.format("*****@*****.**"))
        resp = yield http_client.fetch(
            fe_url,
            method="POST",
            body="",
            headers={'X-Grouper-User': user.username})

    u = User.get(session, name="*****@*****.**")
    assert not u.enabled, "Attempting to enable SAs through groups/enable should not work"
    g = Group.get(session, name="*****@*****.**")
    assert not g.enabled, "Attempting to enable SAs through groups/enable should not work"
Beispiel #30
0
def test_disable_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"))

    disable_role_user(session, user=u)
    u = User.get(session, name="*****@*****.**")
    assert not u.enabled, "The SA User should be disabled"
    g = Group.get(session, name="*****@*****.**")
    assert not g.enabled, "The SA Group should be disabled"

    enable_role_user(session, actor=user, group=g, preserve_membership=True)
    u = User.get(session, name="*****@*****.**")
    assert u.enabled, "The SA User should be enabled"
    g = Group.get(session, name="*****@*****.**")
    assert g.enabled, "The SA Group should be enabled"

    with pytest.raises(HTTPError):
        fe_url = url(base_url, "/groups/{}/disable".format("*****@*****.**"))
        yield http_client.fetch(
            fe_url, method="POST", body="", headers={"X-Grouper-User": user.username}
        )

    u = User.get(session, name="*****@*****.**")
    assert u.enabled, "Attempting to disable SAs through groups/disable should not work"
    g = Group.get(session, name="*****@*****.**")
    assert g.enabled, "Attempting to disable SAs through groups/disable should not work"

    fe_url = url(base_url, "/users/{}/disable".format("*****@*****.**"))
    yield http_client.fetch(
        fe_url, method="POST", body="", headers={"X-Grouper-User": user.username}
    )

    u = User.get(session, name="*****@*****.**")
    assert not u.enabled, "The SA User should be disabled"
    g = Group.get(session, name="*****@*****.**")
    assert not g.enabled, "The SA Group should be disabled"

    with pytest.raises(HTTPError):
        fe_url = url(base_url, "/groups/{}/enable".format("*****@*****.**"))
        yield http_client.fetch(
            fe_url, method="POST", body="", headers={"X-Grouper-User": user.username}
        )

    u = User.get(session, name="*****@*****.**")
    assert not u.enabled, "Attempting to enable SAs through groups/enable should not work"
    g = Group.get(session, name="*****@*****.**")
    assert not g.enabled, "Attempting to enable SAs through groups/enable should not work"