Esempio n. 1
0
 def check_access(session, actor, target):
     return (
         actor.name == target.name
         or user_is_user_admin(session, actor)
         or (target.role_user and can_manage_role_user(session, actor, tuser=target))
         or (target.is_service_account and can_manage_service_account(session, target, actor))
     )
    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))
Esempio n. 3
0
 def check_access(session, actor, target):
     # type: (Session, User, User) -> bool
     return (
         actor.name == target.name
         or (target.role_user and can_manage_role_user(session, actor, tuser=target))
         or (target.is_service_account and can_manage_service_account(session, target, actor))
     )
Esempio n. 4
0
def get_service_account_view_template_vars(session, actor, user, group, graph):
    ret = get_user_view_template_vars(session, actor, user, graph)
    ret.update(get_group_view_template_vars(session, actor, group, graph))
    ret["can_control"] = can_manage_service_account(session, user=actor, tuser=user)
    ret["log_entries"] = sorted(set(get_log_entries_by_user(session, user) +
        group.my_log_entries()), key=lambda x: x.log_time, reverse=True)
    return ret
Esempio n. 5
0
 def check_access(session, actor, target):
     # type: (Session, User, User) -> bool
     return (actor.name == target.name
             or (target.role_user
                 and can_manage_role_user(session, actor, tuser=target))
             or (target.is_service_account
                 and can_manage_service_account(session, target, actor)))
Esempio n. 6
0
def get_user_view_template_vars(session, actor, user, graph):
    # type: (Session, User, User, GroupGraph) -> Dict[str, Any]
    # TODO(cbguder): get around circular dependencies
    from grouper.fe.handlers.user_disable import UserDisable
    from grouper.fe.handlers.user_enable import UserEnable

    ret = {}  # type: Dict[str, Any]
    if user.is_service_account:
        ret["can_control"] = can_manage_service_account(
            session, user.service_account, actor
        ) or user_is_user_admin(session, actor)
        ret["can_disable"] = ret["can_control"]
        ret["can_enable"] = user_is_user_admin(session, actor)
        ret["can_enable_preserving_membership"] = user_is_user_admin(session, actor)
        ret["account"] = user.service_account
    else:
        ret["can_control"] = user.name == actor.name or user_is_user_admin(session, actor)
        ret["can_disable"] = UserDisable.check_access(session, actor, user)
        ret["can_enable_preserving_membership"] = UserEnable.check_access(session, actor, user)
        ret["can_enable"] = UserEnable.check_access_without_membership(session, actor, user)

    if user.id == actor.id:
        ret["num_pending_group_requests"] = user_requests_aggregate(session, actor).count()
        _, ret["num_pending_perm_requests"] = get_requests(
            session, status="pending", limit=1, offset=0, owner=actor
        )
    else:
        ret["num_pending_group_requests"] = None
        ret["num_pending_perm_requests"] = None

    try:
        user_md = graph.get_user_details(user.name)
    except NoSuchUser:
        # Either user is probably very new, so they have no metadata yet, or
        # they're disabled, so we've excluded them from the in-memory graph.
        user_md = {}

    shell_metadata = get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY)
    ret["shell"] = shell_metadata.data_value if shell_metadata else "No shell configured"
    github_username = get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY)
    ret["github_username"] = github_username.data_value if github_username else "(Unset)"
    ret["open_audits"] = user_open_audits(session, user)
    group_edge_list = get_groups_by_user(session, user) if user.enabled else []
    ret["groups"] = [
        {"name": g.name, "type": "Group", "role": ge._role} for g, ge in group_edge_list
    ]
    ret["passwords"] = user_passwords(session, user)
    ret["public_keys"] = get_public_keys_of_user(session, user.id)
    ret["log_entries"] = get_log_entries_by_user(session, user)
    ret["user_tokens"] = user.tokens

    if user.is_service_account:
        service_account = user.service_account
        ret["permissions"] = service_account_permissions(session, service_account)
    else:
        ret["permissions"] = user_md.get("permissions", [])
        for permission in ret["permissions"]:
            permission["granted_on"] = datetime.fromtimestamp(permission["granted_on"])

    return ret
Esempio n. 7
0
 def check_access(session, actor, target):
     return (actor.name == target.name
             or user_is_user_admin(session, actor)
             or (target.role_user
                 and can_manage_role_user(session, actor, tuser=target))
             or (target.is_service_account
                 and can_manage_service_account(session, target, actor)))
Esempio n. 8
0
def get_user_view_template_vars(session, actor, user, graph):
    # TODO(cbguder): get around circular dependencies
    from grouper.fe.handlers.user_disable import UserDisable
    from grouper.fe.handlers.user_enable import UserEnable

    ret = {}
    if user.is_service_account:
        ret["can_control"] = (
            can_manage_service_account(session, user.service_account, actor) or
            user_is_user_admin(session, actor)
        )
        ret["can_disable"] = ret["can_control"]
        ret["can_enable"] = user_is_user_admin(session, actor)
        ret["account"] = user.service_account
    else:
        ret["can_control"] = (user.name == actor.name or user_is_user_admin(session, actor))
        ret["can_disable"] = UserDisable.check_access(session, actor, user)
        ret["can_enable"] = UserEnable.check_access(session, actor, user)

    if user.id == actor.id:
        ret["num_pending_group_requests"] = user_requests_aggregate(session, actor).count()
        _, ret["num_pending_perm_requests"] = get_requests_by_owner(session, actor,
            status='pending', limit=1, offset=0)
    else:
        ret["num_pending_group_requests"] = None
        ret["num_pending_perm_requests"] = None

    try:
        user_md = graph.get_user_details(user.name)
    except NoSuchUser:
        # Either user is probably very new, so they have no metadata yet, or
        # they're disabled, so we've excluded them from the in-memory graph.
        user_md = {}

    shell = (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value
        if get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY)
        else "No shell configured")
    ret["shell"] = shell
    ret["open_audits"] = user_open_audits(session, user)
    group_edge_list = get_groups_by_user(session, user) if user.enabled else []
    ret["groups"] = [{'name': g.name, 'type': 'Group', 'role': ge._role}
        for g, ge in group_edge_list]
    ret["passwords"] = user_passwords(session, user)
    ret["public_keys"] = get_public_keys_of_user(session, user.id)
    for key in ret["public_keys"]:
        key.tags = get_public_key_tags(session, key)
        key.pretty_permissions = ["{} ({})".format(perm.name,
            perm.argument if perm.argument else "unargumented")
            for perm in get_public_key_permissions(session, key)]
    ret["log_entries"] = get_log_entries_by_user(session, user)
    ret["user_tokens"] = user.tokens

    if user.is_service_account:
        service_account = user.service_account
        ret["permissions"] = service_account_permissions(session, service_account)
    else:
        ret["permissions"] = user_md.get('permissions', [])

    return ret
Esempio n. 9
0
def get_service_account_view_template_vars(session, actor, user, group, graph):
    ret = get_user_view_template_vars(session, actor, user, graph)
    ret.update(get_group_view_template_vars(session, actor, group, graph))
    ret["can_control"] = can_manage_service_account(session,
                                                    user=actor,
                                                    tuser=user)
    ret["log_entries"] = sorted(
        set(get_log_entries_by_user(session, user) + group.my_log_entries()),
        key=lambda x: x.log_time,
        reverse=True)
    return ret
Esempio n. 10
0
    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))
Esempio n. 11
0
    def get(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(obj=service_account)

        self.render(
            "service-account-edit.html", service_account=service_account, group=group, form=form
        )
Esempio n. 12
0
    def get(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")
        accountname = self.get_path_argument("accountname")

        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()

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

        form = ServiceAccountEditForm(obj=service_account)

        self.render(
            "service-account-edit.html", service_account=service_account, group=group, form=form
        )
Esempio n. 13
0
    def get(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(obj=service_account)

        self.render("service-account-edit.html",
                    service_account=service_account,
                    group=group,
                    form=form)
Esempio n. 14
0
 def check_access(session, actor, target):
     return actor.name == target.name or (
         target.role_user and can_manage_service_account(session, actor, tuser=target)
     )
 def check_access(session, actor, target):
     if user_has_permission(session, actor, USER_ADMIN):
         return True
     return can_manage_service_account(session, target, actor)
Esempio n. 16
0
def test_service_accounts(
        session,
        standard_graph,
        graph,
        users,
        groups,
        permissions  # noqa: F811
):
    # Create a service account.
    service_account = ServiceAccount.get(session, name="*****@*****.**")
    assert service_account.description == "some service account"
    assert service_account.machine_set == "some machines"
    assert service_account.user.name == "*****@*****.**"
    assert service_account.user.enabled == True
    assert service_account.user.is_service_account == True
    accounts = get_service_accounts(session, groups["team-sre"])
    assert len(accounts) == 1
    assert accounts[0].user.name == "*****@*****.**"
    assert is_service_account(session, service_account.user)

    # Duplicates should raise an exception.
    with pytest.raises(DuplicateServiceAccount):
        create_service_account(session, users["*****@*****.**"], "*****@*****.**",
                               "dup", "dup", groups["team-sre"])

    # zorkian should be able to manage the account, as should gary, but oliver (not a member of the
    # group) should not.
    assert can_manage_service_account(session, service_account,
                                      users["*****@*****.**"])
    assert can_manage_service_account(session, service_account,
                                      users["*****@*****.**"])
    assert not can_manage_service_account(session, service_account,
                                          users["*****@*****.**"])

    # Check that the user appears in the graph.
    graph.update_from_db(session)
    metadata = graph.user_metadata["*****@*****.**"]
    assert metadata["enabled"]
    assert metadata["service_account"]["description"] == "some service account"
    assert metadata["service_account"]["machine_set"] == "some machines"
    assert metadata["service_account"]["owner"] == "team-sre"
    group_details = graph.get_group_details("team-sre")
    assert group_details["service_accounts"] == ["*****@*****.**"]

    # Grant a permission to the service account and check it in the graph.
    grant_permission_to_service_account(session, service_account,
                                        permissions["team-sre"], "*")
    graph.update_from_db(session)
    user_details = graph.get_user_details("*****@*****.**")
    assert user_details["permissions"][0]["permission"] == "team-sre"
    assert user_details["permissions"][0]["argument"] == "*"

    # Diabling the service account should remove the link to the group.
    disable_service_account(session, users["*****@*****.**"], service_account)
    assert service_account.user.enabled == False
    assert get_service_accounts(session, groups["team-sre"]) == []

    # The user should also be gone from the graph and have its permissions removed.
    graph.update_from_db(session)
    group_details = graph.get_group_details("team-sre")
    assert "service_accounts" not in group_details
    metadata = graph.user_metadata["*****@*****.**"]
    assert not metadata["enabled"]
    assert "owner" not in metadata["service_account"]
    user_details = graph.get_user_details("*****@*****.**")
    assert user_details["permissions"] == []

    # We can re-enable and attach to a different group.
    new_group = groups["security-team"]
    enable_service_account(session, users["*****@*****.**"], service_account,
                           new_group)
    assert service_account.user.enabled == True
    assert get_service_accounts(session, groups["team-sre"]) == []
    accounts = get_service_accounts(session, new_group)
    assert len(accounts) == 1
    assert accounts[0].user.name == "*****@*****.**"

    # Check that this is reflected in the graph and the user has no permissions.
    graph.update_from_db(session)
    group_details = graph.get_group_details("security-team")
    assert group_details["service_accounts"] == ["*****@*****.**"]
    metadata = graph.user_metadata["*****@*****.**"]
    assert metadata["service_account"]["owner"] == "security-team"
    user_details = graph.get_user_details("*****@*****.**")
    assert user_details["permissions"] == []
Esempio n. 17
0
 def check_access(session, actor, target):
     return actor.name == target.name or (target.role_user
                                          and can_manage_service_account(
                                              session, actor, tuser=target))
Esempio n. 18
0
def get_user_view_template_vars(session, actor, user, graph):
    # type: (Session, User, User, GroupGraph) -> Dict[str, Any]
    # TODO(cbguder): get around circular dependencies
    from grouper.fe.handlers.user_disable import UserDisable
    from grouper.fe.handlers.user_enable import UserEnable

    ret = {}  # type: Dict[str, Any]
    if user.is_service_account:
        ret["can_control"] = can_manage_service_account(
            session, user.service_account, actor
        ) or user_is_user_admin(session, actor)
        ret["can_disable"] = ret["can_control"]
        ret["can_enable"] = user_is_user_admin(session, actor)
        ret["can_enable_preserving_membership"] = user_is_user_admin(session, actor)
        ret["account"] = user.service_account
    else:
        ret["can_control"] = user.name == actor.name or user_is_user_admin(session, actor)
        ret["can_disable"] = UserDisable.check_access(session, actor, user)
        ret["can_enable_preserving_membership"] = UserEnable.check_access(session, actor, user)
        ret["can_enable"] = UserEnable.check_access_without_membership(session, actor, user)

    if user.id == actor.id:
        ret["num_pending_group_requests"] = user_requests_aggregate(session, actor).count()
        _, ret["num_pending_perm_requests"] = get_requests(
            session, status="pending", limit=1, offset=0, owner=actor
        )
    else:
        ret["num_pending_group_requests"] = None
        ret["num_pending_perm_requests"] = None

    try:
        user_md = graph.get_user_details(user.name)
    except NoSuchUser:
        # Either user is probably very new, so they have no metadata yet, or
        # they're disabled, so we've excluded them from the in-memory graph.
        user_md = {}

    shell = (
        get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY).data_value
        if get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY)
        else "No shell configured"
    )
    ret["shell"] = shell
    github_username = get_user_metadata_by_key(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY)
    ret["github_username"] = github_username.data_value if github_username else "(Unset)"
    ret["open_audits"] = user_open_audits(session, user)
    group_edge_list = get_groups_by_user(session, user) if user.enabled else []
    ret["groups"] = [
        {"name": g.name, "type": "Group", "role": ge._role} for g, ge in group_edge_list
    ]
    ret["passwords"] = user_passwords(session, user)
    ret["public_keys"] = get_public_keys_of_user(session, user.id)
    ret["log_entries"] = get_log_entries_by_user(session, user)
    ret["user_tokens"] = user.tokens

    if user.is_service_account:
        service_account = user.service_account
        ret["permissions"] = service_account_permissions(session, service_account)
    else:
        ret["permissions"] = user_md.get("permissions", [])
        for permission in ret["permissions"]:
            permission["granted_on"] = datetime.fromtimestamp(permission["granted_on"])

    return ret
 def check_access(session, actor, target):
     if user_has_permission(session, actor, USER_ADMIN):
         return True
     return can_manage_service_account(session, target, actor)
Esempio n. 20
0
def test_service_accounts(setup):
    # type: (SetupTest) -> None
    """Tests remaining non-usecase service account functions."""
    with setup.transaction():
        setup.create_service_account("*****@*****.**", "team-sre",
                                     "some machines", "some service account")
        setup.add_user_to_group("*****@*****.**", "team-sre", "owner")
        setup.add_user_to_group("*****@*****.**", "admins")
        setup.grant_permission_to_group(USER_ADMIN, "", "admins")
        setup.add_user_to_group("*****@*****.**", "team-sre")
        setup.create_user("*****@*****.**")
        setup.grant_permission_to_service_account("team-sre", "*",
                                                  "*****@*****.**")
        setup.create_group("security-team")

    group = Group.get(setup.session, name="team-sre")
    assert group
    accounts = get_service_accounts(setup.session, group)
    assert len(accounts) == 1
    service_account = accounts[0]
    assert service_account.user.name == "*****@*****.**"
    assert service_account.user.is_service_account

    # zorkian should be able to manage the account, as should gary, but oliver (not a member of the
    # group) should not.
    zorkian_user = User.get(setup.session, name="*****@*****.**")
    assert zorkian_user
    gary_user = User.get(setup.session, name="*****@*****.**")
    assert gary_user
    oliver_user = User.get(setup.session, name="*****@*****.**")
    assert oliver_user
    assert can_manage_service_account(setup.session, service_account,
                                      zorkian_user)
    assert can_manage_service_account(setup.session, service_account,
                                      gary_user)
    assert not can_manage_service_account(setup.session, service_account,
                                          oliver_user)

    # Diabling the service account should remove the link to the group.
    disable_service_account(setup.session, zorkian_user, service_account)
    assert service_account.user.enabled == False
    assert get_service_accounts(setup.session, group) == []

    # The user should also be gone from the graph and have its permissions removed.
    setup.graph.update_from_db(setup.session)
    group_details = setup.graph.get_group_details("team-sre")
    assert "service_accounts" not in group_details
    metadata = setup.graph.user_metadata["*****@*****.**"]
    assert not metadata["enabled"]
    assert "owner" not in metadata["service_account"]
    user_details = setup.graph.get_user_details("*****@*****.**")
    assert user_details["permissions"] == []

    # We can re-enable and attach to a different group.
    new_group = Group.get(setup.session, name="security-team")
    assert new_group
    enable_service_account(setup.session, zorkian_user, service_account,
                           new_group)
    assert service_account.user.enabled == True
    assert get_service_accounts(setup.session, group) == []
    accounts = get_service_accounts(setup.session, new_group)
    assert len(accounts) == 1
    assert accounts[0].user.name == "*****@*****.**"

    # Check that this is reflected in the graph and the user has no permissions.
    setup.graph.update_from_db(setup.session)
    group_details = setup.graph.get_group_details("security-team")
    assert group_details["service_accounts"] == ["*****@*****.**"]
    metadata = setup.graph.user_metadata["*****@*****.**"]
    assert metadata["service_account"]["owner"] == "security-team"
    user_details = setup.graph.get_user_details("*****@*****.**")
    assert user_details["permissions"] == []
Esempio n. 21
0
 def check_access(session: Session, actor: User,
                  target: ServiceAccount) -> bool:
     if user_has_permission(session, actor, USER_ADMIN):
         return True
     return can_manage_service_account(session, target, actor)
def get_user_view_template_vars(session, actor, user, graph):
    # TODO(cbguder): get around circular dependencies
    from grouper.fe.handlers.user_disable import UserDisable
    from grouper.fe.handlers.user_enable import UserEnable

    ret = {}
    if user.is_service_account:
        ret["can_control"] = (can_manage_service_account(
            session, user.service_account, actor)
                              or user_is_user_admin(session, actor))
        ret["can_disable"] = ret["can_control"]
        ret["can_enable"] = user_is_user_admin(session, actor)
        ret["account"] = user.service_account
    else:
        ret["can_control"] = (user.name == actor.name
                              or user_is_user_admin(session, actor))
        ret["can_disable"] = UserDisable.check_access(session, actor, user)
        ret["can_enable"] = UserEnable.check_access(session, actor, user)

    if user.id == actor.id:
        ret["num_pending_group_requests"] = user_requests_aggregate(
            session, actor).count()
        _, ret["num_pending_perm_requests"] = get_requests_by_owner(
            session, actor, status='pending', limit=1, offset=0)
    else:
        ret["num_pending_group_requests"] = None
        ret["num_pending_perm_requests"] = None

    try:
        user_md = graph.get_user_details(user.name)
    except NoSuchUser:
        # Either user is probably very new, so they have no metadata yet, or
        # they're disabled, so we've excluded them from the in-memory graph.
        user_md = {}

    shell = (get_user_metadata_by_key(session, user.id,
                                      USER_METADATA_SHELL_KEY).data_value
             if get_user_metadata_by_key(session, user.id,
                                         USER_METADATA_SHELL_KEY) else
             "No shell configured")
    ret["shell"] = shell
    ret["open_audits"] = user_open_audits(session, user)
    group_edge_list = get_groups_by_user(session, user) if user.enabled else []
    ret["groups"] = [{
        'name': g.name,
        'type': 'Group',
        'role': ge._role
    } for g, ge in group_edge_list]
    ret["passwords"] = user_passwords(session, user)
    ret["public_keys"] = get_public_keys_of_user(session, user.id)
    for key in ret["public_keys"]:
        key.tags = get_public_key_tags(session, key)
        key.pretty_permissions = [
            "{} ({})".format(
                perm.name, perm.argument if perm.argument else "unargumented")
            for perm in get_public_key_permissions(session, key)
        ]
    ret["log_entries"] = get_log_entries_by_user(session, user)
    ret["user_tokens"] = user.tokens

    if user.is_service_account:
        service_account = user.service_account
        ret["permissions"] = service_account_permissions(
            session, service_account)
    else:
        ret["permissions"] = user_md.get('permissions', [])

    return ret