示例#1
0
    def get(self):
        user = self.get_current_user()
        if not (user_has_permission(self.session, user, AUDIT_VIEWER) or
                user_has_permission(self.session, user, AUDIT_MANAGER)):
            return self.forbidden()

        offset = int(self.get_argument("offset", 0))
        limit = int(self.get_argument("limit", 50))
        if limit > 200:
            limit = 200

        open_filter = self.get_argument("filter", "Open Audits")
        audits = get_audits(self.session, only_open=(open_filter == "Open Audits"))

        open_audits = any([not audit.complete for audit in audits])
        total = audits.count()
        audits = audits.offset(offset).limit(limit).all()

        open_audits = self.session.query(Audit).filter(
            Audit.complete == False).all()
        can_start = user_has_permission(self.session, user, AUDIT_MANAGER)

        # FIXME(herb): make limit selected from ui
        audit_log_entries = AuditLog.get_entries(self.session, category=AuditLogCategory.audit,
                limit=100)

        self.render(
            "audits.html", audits=audits, open_filter=open_filter, can_start=can_start,
            offset=offset, limit=limit, total=total, open_audits=open_audits,
            audit_log_entries=audit_log_entries,
        )
示例#2
0
 def check_access_without_membership(session: Session, actor: User,
                                     target: User) -> bool:
     return (user_has_permission(session, actor, USER_ADMIN)
             or (target.role_user
                 and is_owner_of_role_user(session, actor, tuser=target))
             or user_has_permission(
                 session, actor, USER_ENABLE, argument=target.name))
示例#3
0
    def get(self):
        user = self.get_current_user()
        if not (user_has_permission(self.session, user, AUDIT_VIEWER) or
                user_has_permission(self.session, user, AUDIT_MANAGER)):
            return self.forbidden()

        offset = int(self.get_argument("offset", 0))
        limit = int(self.get_argument("limit", 50))
        if limit > 200:
            limit = 200

        open_filter = self.get_argument("filter", "Open Audits")
        audits = get_audits(self.session, only_open=(open_filter == "Open Audits"))

        open_audits = any([not audit.complete for audit in audits])
        total = audits.count()
        audits = audits.offset(offset).limit(limit).all()

        open_audits = self.session.query(Audit).filter(
            Audit.complete == False).all()
        can_start = user_has_permission(self.session, user, AUDIT_MANAGER)

        # FIXME(herb): make limit selected from ui
        audit_log_entries = AuditLog.get_entries(self.session, category=AuditLogCategory.audit,
                limit=100)

        self.render(
            "audits.html", audits=audits, open_filter=open_filter, can_start=can_start,
            offset=offset, limit=limit, total=total, open_audits=open_audits,
            audit_log_entries=audit_log_entries,
        )
示例#4
0
    def post(self, name=None, mapping_id=None):
        mapping = TagPermissionMap.get(self.session, id=mapping_id)
        if not mapping:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT,
                                   mapping.tag.name):
            return self.forbidden()

        permission = mapping.permission
        tag = mapping.tag

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

        AuditLog.log(
            self.session,
            self.current_user.id,
            "revoke_tag_permission",
            "Revoked permission with argument: {}".format(mapping.argument),
            on_tag_id=tag.id,
            on_permission_id=permission.id,
        )

        return self.redirect("/tags/{}?refresh=yes".format(tag.name))
示例#5
0
def can_manage_role_user(session, user, tuser=None, tgroup=None):
    # type: (Session, User, User, Group) -> bool
    """
    Indicates whether the user has permission to manage the service account
    that tuser/tgroup is part of

    Args:
        session: the database session
        user: the User whose permissions are being verified
        tuser: the service account User we're checking to see can be managed
        tgroup: the service account Group we're checking to see can be managed

    Returns:
        a boolean indicating if user can manage the service account of tuser/tgroup
    """
    try:
        target = get_role_user(session, tuser, tgroup)
    except RoleUserNotFound:
        return False

    if target.user.name == user.name:
        return True

    if user_can_manage_group(session, target.group, user):
        return True

    return user_has_permission(session, user, USER_ADMIN)
示例#6
0
def is_owner_of_role_user(session, user, tuser=None, tgroup=None):
    # type: (Session, User, User, Group) -> bool
    """
    Indicates whether the user is an owner of the service account
    that tuser/tgroup is part of

    Args:
        session: the database session
        user: the User whose permissions are being verified
        tuser: the service account User we're checking to see is owned
        tgroup: the service account Group we're checking to see is owned

    Returns:
        a boolean indicating if user is an owner of the service account of tuser/tgroup
    """
    try:
        target = get_role_user(session, tuser, tgroup)
    except RoleUserNotFound:
        return False

    if target.user.name == user.name:
        return True

    if user.name in target.group.my_owners_as_strings():
        return True

    return user_has_permission(session, user, USER_ADMIN)
示例#7
0
def can_manage_role_user(session, user, tuser=None, tgroup=None):
    # type: (Session, User, User, Group) -> bool
    """
    Indicates whether the user has permission to manage the service account
    that tuser/tgroup is part of

    Args:
        session: the database session
        user: the User whose permissions are being verified
        tuser: the service account User we're checking to see can be managed
        tgroup: the service account Group we're checking to see can be managed

    Returns:
        a boolean indicating if user can manage the service account of tuser/tgroup
    """
    try:
        target = get_role_user(session, tuser, tgroup)
    except RoleUserNotFound:
        return False

    if target.user.name == user.name:
        return True

    if user_can_manage_group(session, target.group, user):
        return True

    return user_has_permission(session, user, USER_ADMIN)
示例#8
0
def is_owner_of_role_user(session, user, tuser=None, tgroup=None):
    # type: (Session, User, User, Group) -> bool
    """
    Indicates whether the user is an owner of the service account
    that tuser/tgroup is part of

    Args:
        session: the database session
        user: the User whose permissions are being verified
        tuser: the service account User we're checking to see is owned
        tgroup: the service account Group we're checking to see is owned

    Returns:
        a boolean indicating if user is an owner of the service account of tuser/tgroup
    """
    try:
        target = get_role_user(session, tuser, tgroup)
    except RoleUserNotFound:
        return False

    if target.user.name == user.name:
        return True

    if user.name in target.group.my_owners_as_strings():
        return True

    return user_has_permission(session, user, USER_ADMIN)
示例#9
0
    def post(self, tag_id=None, name=None):
        tag = PublicKeyTag.get(self.session, tag_id, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name):
            return self.forbidden()

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

        tag.description = form.data["description"]
        tag.enabled = form.data["enabled"]
        Counter.incr(self.session, "updates")

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

        AuditLog.log(self.session, self.current_user.id, 'edit_tag',
                     'Edited tag.', on_tag_id=tag.id)

        return self.redirect("/tags/{}".format(tag.name))
示例#10
0
    def get(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        if not user_has_permission(self.session, self.current_user,
                                   AUDIT_MANAGER):
            return self.forbidden()

        self.render("audit-create.html", form=AuditCreateForm())
示例#11
0
    def get(self):
        user = self.get_current_user()
        if not user_has_permission(self.session, user, AUDIT_MANAGER):
            return self.forbidden()

        self.render(
            "audit-create.html", form=AuditCreateForm(),
        )
示例#12
0
    def get(self):
        user = self.get_current_user()
        if not user_has_permission(self.session, user, AUDIT_MANAGER):
            return self.forbidden()

        self.render(
            "audit-create.html",
            form=AuditCreateForm(),
        )
示例#13
0
    def get(self, name=None, mapping_id=None):

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

        if not user_has_permission(self.session, self.current_user, TAG_EDIT, mapping.tag.name):
            return self.forbidden()

        self.render("permission-revoke-tag.html", mapping=mapping)
    def post(self, name=None):
        tag = PublicKeyTag.get(self.session, None, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT,
                                   tag.name):
            return self.forbidden()

        form = PermissionGrantTagForm(self.request.arguments)
        form.permission.choices = [["", "(select one)"]]

        for perm in get_all_permissions(self.session):
            form.permission.choices.append(
                [perm.name, "{} (*)".format(perm.name)])

        if not form.validate():
            return self.render(
                "permission-grant-tag.html",
                form=form,
                tag=tag,
                alerts=self.get_form_alerts(form.errors),
            )

        permission = get_permission(self.session, form.data["permission"])
        if not permission:
            return self.notfound()  # Shouldn't happen.

        success = grant_permission_to_tag(self.session,
                                          tag.id,
                                          permission.id,
                                          argument=form.data["argument"])

        if not success:
            form.argument.errors.append(
                "Permission and Argument already mapped to this tag.")
            return self.render(
                "permission-grant-tag.html",
                form=form,
                tag=tag,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(
            self.session,
            self.current_user.id,
            "grant_permission_tag",
            "Granted permission with argument: {}".format(
                form.data["argument"]),
            on_permission_id=permission.id,
            on_tag_id=tag.id,
        )

        return self.redirect("/tags/{}?refresh=yes".format(tag.name))
示例#15
0
    def get(self, name=None, mapping_id=None):

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

        if not user_has_permission(self.session, self.current_user, TAG_EDIT,
                                   mapping.tag.name):
            return self.forbidden()

        self.render("permission-revoke-tag.html", mapping=mapping)
示例#16
0
    def get(self, tag_id=None, name=None):
        tag = PublicKeyTag.get(self.session, tag_id, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name):
            return self.forbidden()

        form = TagEditForm(obj=tag)

        self.render("tag-edit.html", tag=tag, form=form)
示例#17
0
    def get(self, tag_id=None, name=None):
        tag = PublicKeyTag.get(self.session, tag_id, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT,
                                   tag.name):
            return self.forbidden()

        form = TagEditForm(obj=tag)

        self.render("tag-edit.html", tag=tag, form=form)
    def post(self, user_id=None, name=None):
        if not (
            user_is_permission_admin(self.session, self.current_user)
            or user_has_permission(self.session, self.current_user, AUDIT_MANAGER)
        ):
            return self.forbidden()

        try:
            disable_permission_auditing(self.session, name, self.current_user.id)
        except NoSuchPermission:
            return self.notfound()

        # No explicit refresh because handler queries SQL.
        return self.redirect("/permissions/{}".format(name))
示例#19
0
    def get(self, tag_id=None, name=None):
        self.handle_refresh()
        tag = PublicKeyTag.get(self.session, tag_id, name)
        if not tag:
            return self.notfound()

        permissions = get_public_key_tag_permissions(self.session, tag)
        log_entries = tag.my_log_entries()
        is_owner = user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name)
        can_grant = self.session.query(Permission).all() if is_owner else []

        self.render(
            "tag.html", tag=tag, permissions=permissions, can_grant=can_grant,
            log_entries=log_entries, is_owner=is_owner,
        )
示例#20
0
    def get(self, tag_id=None, name=None):
        self.handle_refresh()
        tag = PublicKeyTag.get(self.session, tag_id, name)
        if not tag:
            return self.notfound()

        permissions = get_public_key_tag_permissions(self.session, tag)
        log_entries = tag.my_log_entries()
        is_owner = user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name)
        can_grant = self.session.query(Permission).all() if is_owner else []

        self.render(
            "tag.html", tag=tag, permissions=permissions, can_grant=can_grant,
            log_entries=log_entries, is_owner=is_owner,
        )
    def post(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

        if not (user_is_permission_admin(self.session, self.current_user)
                or user_has_permission(self.session, self.current_user,
                                       AUDIT_MANAGER)):
            return self.forbidden()

        try:
            disable_permission_auditing(self.session, name,
                                        self.current_user.id)
        except NoSuchPermission:
            return self.notfound()

        # No explicit refresh because handler queries SQL.
        return self.redirect("/permissions/{}".format(name))
    def get(self, name=None):
        tag = PublicKeyTag.get(self.session, None, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT,
                                   tag.name):
            return self.forbidden()

        form = PermissionGrantTagForm()
        form.permission.choices = [["", "(select one)"]]

        for perm in get_all_permissions(self.session):
            form.permission.choices.append(
                [perm.name, "{} (*)".format(perm.name)])

        return self.render("permission-grant-tag.html", form=form, tag=tag)
示例#23
0
    def get(self, name=None):
        tag = PublicKeyTag.get(self.session, None, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name):
            return self.forbidden()

        form = PermissionGrantTagForm()
        form.permission.choices = [["", "(select one)"]]

        for perm in self.session.query(Permission).all():
            form.permission.choices.append([perm.name, "{} (*)".format(perm.name)])

        return self.render(
            "permission-grant-tag.html", form=form, tag=tag,
        )
示例#24
0
def test_has_permission(session, standard_graph, users):  # noqa
    """ Tests the has_permission method of a user object. """

    # In our setup, zorkian has 'audited' with no arguments
    assert user_has_permission(session, users["*****@*****.**"], "audited"), "zorkian has permission audited"
    assert not user_has_permission(session, users["*****@*****.**"], "audited", argument='foo'), \
        "zorkian has permission audited:foo"
    assert not user_has_permission(session, users["*****@*****.**"], "audited", argument='*'), \
        "zorkian has permission audited:*"

    # zay has ssh:*
    assert user_has_permission(session, users["*****@*****.**"], "ssh"), "zay has permission ssh"
    assert user_has_permission(session, users["*****@*****.**"], "ssh", argument='foo'), "zay has permission ssh:foo"
    assert user_has_permission(session, users["*****@*****.**"], "ssh", argument='*'), "zay has permission ssh:*"
示例#25
0
    def expire_nonauditors(self, session):
        """Checks all enabled audited groups and ensures that all approvers for that group have
        the PERMISSION_AUDITOR permission. All approvers of audited groups that aren't auditors
        have their membership in the audited group set to expire
        settings.nonauditor_expiration_days days in the future.

        Args:
            session (Session): database session
        """
        now = datetime.utcnow()
        graph = Graph()
        exp_days = timedelta(days=settings.nonauditor_expiration_days)
        # Hack to ensure the graph is loaded before we access it
        graph.update_from_db(session)
        # TODO(tyleromeara): replace with graph call
        for group in get_audited_groups(session):
            members = group.my_members()
            # Go through every member of the group and set them to expire if they are an approver
            # but not an auditor
            for (type_, member), edge in members.iteritems():
                # Auditing is already inherited, so we don't need to handle that here
                if type_ == "Group":
                    continue
                member = User.get(session, name=member)
                member_is_approver = user_role_index(
                    member, members) in APPROVER_ROLE_INDICIES
                member_is_auditor = user_has_permission(
                    session, member, PERMISSION_AUDITOR)
                if not member_is_approver or member_is_auditor:
                    continue
                edge = GroupEdge.get(session, id=edge.edge_id)
                if edge.expiration and edge.expiration < now + exp_days:
                    continue
                exp = now + exp_days
                exp = exp.date()
                edge.apply_changes_dict({
                    "expiration":
                    "{}/{}/{}".format(exp.month, exp.day, exp.year)
                })
                edge.add(session)
                notify_nonauditor_flagged(settings, session, edge)
        session.commit()
示例#26
0
    def post(self, name=None, mapping_id=None):
        mapping = TagPermissionMap.get(self.session, id=mapping_id)
        if not mapping:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT, mapping.tag.name):
            return self.forbidden()

        permission = mapping.permission
        tag = mapping.tag

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

        AuditLog.log(self.session, self.current_user.id, 'revoke_tag_permission',
                     'Revoked permission with argument: {}'.format(mapping.argument),
                     on_tag_id=tag.id, on_permission_id=permission.id)

        return self.redirect('/tags/{}?refresh=yes'.format(tag.name))
示例#27
0
    def post(self, name=None):
        tag = PublicKeyTag.get(self.session, None, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT, tag.name):
            return self.forbidden()

        form = PermissionGrantTagForm(self.request.arguments)
        form.permission.choices = [["", "(select one)"]]

        for perm in self.session.query(Permission).all():
            form.permission.choices.append([perm.name, "{} (*)".format(perm.name)])

        if not form.validate():
            return self.render(
                "permission-grant-tag.html", form=form, tag=tag,
                alerts=self.get_form_alerts(form.errors)
            )

        permission = Permission.get(self.session, form.data["permission"])
        if not permission:
            return self.notfound()  # Shouldn't happen.

        success = grant_permission_to_tag(self.session, tag.id, permission.id,
                                    argument=form.data["argument"])

        if not success:
            form.argument.errors.append(
                "Permission and Argument already mapped to this tag."
            )
            return self.render(
                "permission-grant-tag.html", form=form, tag=tag,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(self.session, self.current_user.id, 'grant_permission_tag',
                     'Granted permission with argument: {}'.format(form.data["argument"]),
                     on_permission_id=permission.id, on_tag_id=tag.id)

        return self.redirect("/tags/{}?refresh=yes".format(tag.name))
示例#28
0
    def get(self, name=None):
        # TODO: use cached data instead, add refresh to appropriate redirects.
        permission = get_permission(self.session, name)
        if not permission:
            return self.notfound()

        can_change_audit_status = user_is_permission_admin(
            self.session, self.current_user) or user_has_permission(
                self.session, self.current_user, AUDIT_MANAGER)
        can_disable = user_is_permission_admin(self.session, self.current_user)
        mapped_groups = get_groups_by_permission(self.session, permission)
        log_entries = get_log_entries_by_permission(self.session, permission)

        self.render(
            "permission.html",
            permission=permission,
            can_disable=can_disable,
            mapped_groups=mapped_groups,
            log_entries=log_entries,
            can_change_audit_status=can_change_audit_status,
        )
示例#29
0
    def expire_nonauditors(self, session):
        # type: (Session) -> None
        """Checks all enabled audited groups and ensures that all approvers for that group have
        the PERMISSION_AUDITOR permission. All approvers of audited groups that aren't auditors
        have their membership in the audited group set to expire
        settings.nonauditor_expiration_days days in the future.

        Args:
            session (Session): database session
        """
        now = datetime.utcnow()
        graph = Graph()
        exp_days = timedelta(days=self.settings.nonauditor_expiration_days)
        # Hack to ensure the graph is loaded before we access it
        graph.update_from_db(session)
        # TODO(tyleromeara): replace with graph call
        for group in get_audited_groups(session):
            members = group.my_members()
            # Go through every member of the group and set them to expire if they are an approver
            # but not an auditor
            for (type_, member), edge in members.iteritems():
                # Auditing is already inherited, so we don't need to handle that here
                if type_ == "Group":
                    continue
                member = User.get(session, name=member)
                member_is_approver = user_role_index(member, members) in APPROVER_ROLE_INDICES
                member_is_auditor = user_has_permission(session, member, PERMISSION_AUDITOR)
                if not member_is_approver or member_is_auditor:
                    continue
                edge = GroupEdge.get(session, id=edge.edge_id)
                if edge.expiration and edge.expiration < now + exp_days:
                    continue
                exp = (now + exp_days).date()
                edge.apply_changes(
                    {"expiration": "{}/{}/{}".format(exp.month, exp.day, exp.year)}
                )
                edge.add(session)
                notify_nonauditor_flagged(self.settings, session, edge)
        session.commit()
示例#30
0
    def post(self, tag_id=None, name=None):
        tag = PublicKeyTag.get(self.session, tag_id, name)
        if not tag:
            return self.notfound()

        if not user_has_permission(self.session, self.current_user, TAG_EDIT,
                                   tag.name):
            return self.forbidden()

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

        tag.description = form.data["description"]
        tag.enabled = form.data["enabled"]
        Counter.incr(self.session, "updates")

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

        AuditLog.log(self.session,
                     self.current_user.id,
                     "edit_tag",
                     "Edited tag.",
                     on_tag_id=tag.id)

        return self.redirect("/tags/{}".format(tag.name))
示例#31
0
def test_has_permission(session, standard_graph, users):  # noqa
    """ Tests the has_permission method of a user object. """

    # In our setup, zorkian has 'audited' with no arguments
    assert user_has_permission(session, users["*****@*****.**"],
                               "audited"), "zorkian has permission audited"
    assert not user_has_permission(session, users["*****@*****.**"], "audited", argument='foo'), \
        "zorkian has permission audited:foo"
    assert not user_has_permission(session, users["*****@*****.**"], "audited", argument='*'), \
        "zorkian has permission audited:*"

    # zay has ssh:*
    assert user_has_permission(session, users["*****@*****.**"],
                               "ssh"), "zay has permission ssh"
    assert user_has_permission(session,
                               users["*****@*****.**"],
                               "ssh",
                               argument='foo'), "zay has permission ssh:foo"
    assert user_has_permission(session, users["*****@*****.**"], "ssh",
                               argument='*'), "zay has permission ssh:*"
 def check_access(session, actor, target):
     if user_has_permission(session, actor, USER_ADMIN):
         return True
     return can_manage_service_account(session, target, actor)
示例#33
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)
示例#34
0
    def get(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        if not user_has_permission(self.session, self.current_user, AUDIT_MANAGER):
            return self.forbidden()

        self.render("audit-create.html", form=AuditCreateForm())
示例#35
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        form = AuditCreateForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "audit-create.html", form=form, alerts=self.get_form_alerts(form.errors)
            )

        if not user_has_permission(self.session, self.current_user, AUDIT_MANAGER):
            return self.forbidden()

        # Step 1, detect if there are non-completed audits and fail if so.
        open_audits = self.session.query(Audit).filter(Audit.complete == False).all()
        if open_audits:
            raise Exception("Sorry, there are audits in progress.")
        ends_at = datetime.strptime(form.data["ends_at"], "%m/%d/%Y")

        # Step 2, find all audited groups and schedule audits for each.
        audited_groups = []
        for groupname in self.graph.groups:
            if not self.graph.get_group_details(groupname)["audited"]:
                continue
            group = Group.get(self.session, name=groupname)
            audit = Audit(group_id=group.id, ends_at=ends_at)
            try:
                audit.add(self.session)
                self.session.flush()
            except IntegrityError:
                self.session.rollback()
                raise Exception("Failed to start the audit. Please try again.")

            # Update group with new audit
            audited_groups.append(group)
            group.audit_id = audit.id

            # Step 3, now get all members of this group and set up audit rows for those edges.
            for member in itervalues(group.my_members()):
                auditmember = AuditMember(audit_id=audit.id, edge_id=member.edge_id)
                try:
                    auditmember.add(self.session)
                except IntegrityError:
                    self.session.rollback()
                    raise Exception("Failed to start the audit. Please try again.")

        self.session.commit()

        AuditLog.log(
            self.session,
            self.current_user.id,
            "start_audit",
            "Started global audit.",
            category=AuditLogCategory.audit,
        )

        # Calculate schedule of emails, basically we send emails at various periods in advance
        # of the end of the audit period.
        schedule_times = []
        not_before = datetime.utcnow() + timedelta(1)
        for days_prior in (28, 21, 14, 7, 3, 1):
            email_time = ends_at - timedelta(days_prior)
            email_time.replace(hour=17, minute=0, second=0)
            if email_time > not_before:
                schedule_times.append((days_prior, email_time))

        # Now send some emails. We do this separately/later to ensure that the audits are all
        # created. Email notifications are sent multiple times if group audits are still
        # outstanding.
        for group in audited_groups:
            mail_to = [
                member.name
                for member in group.my_users()
                if GROUP_EDGE_ROLES[member.role] in ("owner", "np-owner")
            ]

            send_email(
                self.session,
                mail_to,
                "Group Audit: {}".format(group.name),
                "audit_notice",
                settings(),
                {"group": group.name, "ends_at": ends_at},
            )

            for days_prior, email_time in schedule_times:
                send_async_email(
                    self.session,
                    mail_to,
                    "Group Audit: {} - {} day(s) left".format(group.name, days_prior),
                    "audit_notice_reminder",
                    settings(),
                    {"group": group.name, "ends_at": ends_at, "days_left": days_prior},
                    email_time,
                    async_key="audit-{}".format(group.id),
                )

        return self.redirect("/audits")
示例#36
0
    def post(self, audit_id):
        if not user_has_permission(self.session, self.current_user,
                                   PERMISSION_AUDITOR):
            return self.forbidden()

        audit = self.session.query(Audit).filter(Audit.id == audit_id).one()

        # only owners can complete
        owner_ids = {member.id for member in audit.group.my_owners().values()}
        if self.current_user.id not in owner_ids:
            return self.forbidden()

        if audit.complete:
            return self.redirect("/groups/{}".format(audit.group.name))

        edges = {}
        for argument in self.request.arguments:
            if argument.startswith("audit_"):
                edges[int(argument.split("_")
                          [1])] = self.request.arguments[argument][0].decode()

        for audit_member_info in get_group_audit_members_infos(
                self.session, audit.group):
            if audit_member_info.audit_member_obj.id in edges:
                # You can only approve yourself (otherwise you can remove yourself
                # from the group and leave it ownerless)
                if audit_member_info.member_obj.id == self.current_user.id:
                    audit_member_info.audit_member_obj.status = "approved"
                elif edges[audit_member_info.audit_member_obj.
                           id] in AUDIT_STATUS_CHOICES:
                    audit_member_info.audit_member_obj.status = edges[
                        audit_member_info.audit_member_obj.id]

        self.session.commit()

        # If there are still pending statuses, then redirect to the group page.
        if group_has_pending_audit_members(self.session, audit.group):
            return self.redirect("/groups/{}".format(audit.group.name))

        # Complete audits have to be "enacted" now. This means anybody marked as remove has to
        # be removed from the group now.
        try:
            for audit_member_info in get_group_audit_members_infos(
                    self.session, audit.group):
                member_obj = audit_member_info.member_obj
                if audit_member_info.audit_member_obj.status == "remove":
                    audit.group.revoke_member(self.current_user, member_obj,
                                              "Revoked as part of audit.")
                    AuditLog.log(
                        self.session,
                        self.current_user.id,
                        "remove_member",
                        "Removed membership in audit: {}".format(
                            member_obj.name),
                        on_group_id=audit.group.id,
                        on_user_id=member_obj.id,
                        category=AuditLogCategory.audit,
                    )
        except PluginRejectedGroupMembershipUpdate as e:
            alert = Alert("danger", str(e))
            return self.redirect("/groups/{}".format(audit.group.name),
                                 alerts=[alert])

        audit.complete = True
        self.session.commit()

        # Now cancel pending emails
        cancel_async_emails(self.session, "audit-{}".format(audit.group.id))

        AuditLog.log(
            self.session,
            self.current_user.id,
            "complete_audit",
            "Completed group audit.",
            on_group_id=audit.group.id,
            category=AuditLogCategory.audit,
        )

        # check if all audits are complete
        if get_audits(self.session, only_open=True).count() == 0:
            AuditLog.log(
                self.session,
                self.current_user.id,
                "complete_global_audit",
                "last open audit have been completed",
                category=AuditLogCategory.audit,
            )

        return self.redirect("/groups/{}".format(audit.group.name))
 def check_access(session, actor, target):
     return user_has_permission(session, actor, USER_ADMIN)
示例#38
0
    def post(self, audit_id):
        user = self.get_current_user()
        if not user_has_permission(self.session, user, PERMISSION_AUDITOR):
            return self.forbidden()

        audit = self.session.query(Audit).filter(Audit.id == audit_id).one()

        # only owners can complete
        owner_ids = {member.id for member in audit.group.my_owners().values()}
        if user.id not in owner_ids:
            return self.forbidden()

        if audit.complete:
            return self.redirect("/groups/{}".format(audit.group.name))

        edges = {}
        for argument in self.request.arguments:
            if argument.startswith('audit_'):
                edges[int(argument.split('_')[1])] = self.request.arguments[argument][0]

        for member in audit.my_members():
            if member.id in edges:
                # You can only approve yourself (otherwise you can remove yourself
                # from the group and leave it ownerless)
                if member.member.id == user.id:
                    member.status = "approved"
                elif edges[member.id] in AUDIT_STATUS_CHOICES:
                    member.status = edges[member.id]

        self.session.commit()

        # Now if it's completable (no pendings) then mark it complete, else redirect them
        # to the group page.
        if not audit.completable:
            return self.redirect('/groups/{}'.format(audit.group.name))

        # Complete audits have to be "enacted" now. This means anybody marked as remove has to
        # be removed from the group now.
        for member in audit.my_members():
            if member.status == "remove":
                audit.group.revoke_member(self.current_user, member.member,
                                          "Revoked as part of audit.")
                AuditLog.log(self.session, self.current_user.id, 'remove_member',
                             'Removed membership in audit: {}'.format(member.member.name),
                             on_group_id=audit.group.id, on_user_id=member.member.id,
                             category=AuditLogCategory.audit)

        audit.complete = True
        self.session.commit()

        # Now cancel pending emails
        cancel_async_emails(self.session, 'audit-{}'.format(audit.group.id))

        AuditLog.log(self.session, self.current_user.id, 'complete_audit',
                     'Completed group audit.', on_group_id=audit.group.id,
                     category=AuditLogCategory.audit)

        # check if all audits are complete
        if get_audits(self.session, only_open=True).count() == 0:
            AuditLog.log(self.session, self.current_user.id, 'complete_global_audit',
                    'last open audit have been completed', category=AuditLogCategory.audit)

        return self.redirect('/groups/{}'.format(audit.group.name))
示例#39
0
 def check_access(session, actor, target):
     return (user_has_permission(session, actor, USER_ADMIN)
             or user_has_permission(
                 session, actor, USER_ENABLE, argument=target.name)
             or (target.role_user and is_owner_of_service_account(
                 session, actor, tuser=target)))
示例#40
0
def test_exclude_disabled_permissions(
    session, standard_graph, graph, users, groups, permissions  # noqa: F811
):
    """
    Ensure that disabled permissions are excluded from various
    functions/methods that return data from the models.
    """
    perm_ssh = get_permission(session, "ssh")
    perm_grant = create_permission(session, PERMISSION_GRANT)
    session.commit()
    # this user has grouper.permission.grant with argument "ssh/*"
    grant_permission(groups["group-admins"], perm_grant, argument="ssh/*")
    graph.update_from_db(session)

    grant_perms = [
        x for x in user_permissions(session, users["*****@*****.**"]) if x.name == PERMISSION_GRANT
    ]
    assert "ssh" == filter_grantable_permissions(session, grant_perms)[0][0].name
    assert "ssh" in (p.name for p in get_all_permissions(session))
    assert "ssh" in (p.name for p in get_all_permissions(session, include_disabled=False))
    assert "ssh" in (p.name for p in get_all_permissions(session, include_disabled=True))
    assert "ssh" in get_grantable_permissions(session, [])
    assert "team-sre" in [g[0] for g in get_groups_by_permission(session, perm_ssh)]
    assert get_owner_arg_list(session, perm_ssh, "*")
    assert "ssh" in get_owners_by_grantable_permission(session)
    assert "ssh" in (x[0].name for x in user_grantable_permissions(session, users["*****@*****.**"]))
    assert user_has_permission(session, users["*****@*****.**"], "ssh")
    assert "ssh" in (p.name for p in user_permissions(session, users["*****@*****.**"]))
    assert "ssh" in (p["permission"] for p in graph.get_group_details("team-sre")["permissions"])
    assert "ssh" in (pt.name for pt in graph.get_permissions())
    assert "team-sre" in graph.get_permission_details("ssh")["groups"]
    assert "ssh" in (p["permission"] for p in graph.get_user_details("*****@*****.**")["permissions"])

    # now disable the ssh permission
    disable_permission(session, "ssh", users["*****@*****.**"].id)
    graph.update_from_db(session)

    grant_perms = [
        x for x in user_permissions(session, users["*****@*****.**"]) if x.name == PERMISSION_GRANT
    ]
    assert not filter_grantable_permissions(session, grant_perms)
    assert "ssh" not in (p.name for p in get_all_permissions(session))
    assert "ssh" not in (p.name for p in get_all_permissions(session, include_disabled=False))
    assert "ssh" in (p.name for p in get_all_permissions(session, include_disabled=True))
    assert "ssh" not in get_grantable_permissions(session, [])
    assert not get_groups_by_permission(session, perm_ssh)
    assert not get_owner_arg_list(session, perm_ssh, "*")
    assert "ssh" not in get_owners_by_grantable_permission(session)
    assert "ssh" not in (
        x[0].name for x in user_grantable_permissions(session, users["*****@*****.**"])
    )
    assert not user_has_permission(session, users["*****@*****.**"], "ssh")
    assert "ssh" not in (p.name for p in user_permissions(session, users["*****@*****.**"]))
    assert "ssh" not in (
        p["permission"] for p in graph.get_group_details("team-sre")["permissions"]
    )
    assert "ssh" not in (pt.name for pt in graph.get_permissions())
    assert not graph.get_permission_details("ssh")["groups"]
    assert "ssh" not in (
        p["permission"] for p in graph.get_user_details("*****@*****.**")["permissions"]
    )
示例#41
0
 def check_access(session: Session, actor: User, target: User) -> bool:
     return user_has_permission(session, actor, USER_ADMIN) or (
         target.role_user
         and is_owner_of_role_user(session, actor, tuser=target))
示例#42
0
 def check_access(session: Session, actor: User, target: User) -> bool:
     return (user_has_permission(session, actor, USER_ADMIN)
             or user_has_permission(
                 session, actor, USER_DISABLE, argument=target.name)
             or (target.role_user
                 and is_owner_of_role_user(session, actor, tuser=target)))
示例#43
0
 def check_access(session: Session, actor: User,
                  target: ServiceAccount) -> bool:
     return user_has_permission(session, actor, USER_ADMIN)
示例#44
0
    def post(self):
        form = AuditCreateForm(self.request.arguments)
        if not form.validate():
            return self.render("audit-create.html",
                               form=form,
                               alerts=self.get_form_alerts(form.errors))

        user = self.get_current_user()
        if not user_has_permission(self.session, user, AUDIT_MANAGER):
            return self.forbidden()

        # Step 1, detect if there are non-completed audits and fail if so.
        open_audits = self.session.query(Audit).filter(
            Audit.complete == False).all()
        if open_audits:
            raise Exception("Sorry, there are audits in progress.")
        ends_at = datetime.strptime(form.data["ends_at"], "%m/%d/%Y")

        # Step 2, find all audited groups and schedule audits for each.
        audited_groups = []
        for groupname in self.graph.groups:
            if not self.graph.get_group_details(groupname)["audited"]:
                continue
            group = Group.get(self.session, name=groupname)
            audit = Audit(group_id=group.id, ends_at=ends_at)
            try:
                audit.add(self.session)
                self.session.flush()
            except IntegrityError:
                self.session.rollback()
                raise Exception("Failed to start the audit. Please try again.")

            # Update group with new audit
            audited_groups.append(group)
            group.audit_id = audit.id

            # Step 3, now get all members of this group and set up audit rows for those edges.
            for member in group.my_members().values():
                auditmember = AuditMember(audit_id=audit.id,
                                          edge_id=member.edge_id)
                try:
                    auditmember.add(self.session)
                except IntegrityError:
                    self.session.rollback()
                    raise Exception(
                        "Failed to start the audit. Please try again.")

        self.session.commit()

        AuditLog.log(
            self.session,
            self.current_user.id,
            "start_audit",
            "Started global audit.",
            category=AuditLogCategory.audit,
        )

        # Calculate schedule of emails, basically we send emails at various periods in advance
        # of the end of the audit period.
        schedule_times = []
        not_before = datetime.utcnow() + timedelta(1)
        for days_prior in (28, 21, 14, 7, 3, 1):
            email_time = ends_at - timedelta(days_prior)
            email_time.replace(hour=17, minute=0, second=0)
            if email_time > not_before:
                schedule_times.append((days_prior, email_time))

        # Now send some emails. We do this separately/later to ensure that the audits are all
        # created. Email notifications are sent multiple times if group audits are still
        # outstanding.
        for group in audited_groups:
            mail_to = [
                member.name for member in group.my_users()
                if GROUP_EDGE_ROLES[member.role] in ("owner", "np-owner")
            ]

            send_email(
                self.session,
                mail_to,
                "Group Audit: {}".format(group.name),
                "audit_notice",
                settings,
                {
                    "group": group.name,
                    "ends_at": ends_at
                },
            )

            for days_prior, email_time in schedule_times:
                send_async_email(
                    self.session,
                    mail_to,
                    "Group Audit: {} - {} day(s) left".format(
                        group.name, days_prior),
                    "audit_notice_reminder",
                    settings,
                    {
                        "group": group.name,
                        "ends_at": ends_at,
                        "days_left": days_prior
                    },
                    email_time,
                    async_key="audit-{}".format(group.id),
                )

        return self.redirect("/audits")
示例#45
0
 def check_access(session, actor, target):
     return user_has_permission(session, actor, USER_ADMIN)
示例#46
0
 def check_access(session, actor, target):
     return (
         user_has_permission(session, actor, USER_ADMIN)
         or user_has_permission(session, actor, USER_DISABLE, argument=target.name)
         or (target.role_user and is_owner_of_role_user(session, actor, tuser=target))
     )
示例#47
0
 def check_access(session, actor, target):
     return user_has_permission(session, actor, USER_ADMIN) or (
         target.role_user and is_owner_of_role_user(session, actor, tuser=target)
     )
示例#48
0
    def post(self, audit_id):
        user = self.get_current_user()
        if not user_has_permission(self.session, user, PERMISSION_AUDITOR):
            return self.forbidden()

        audit = self.session.query(Audit).filter(Audit.id == audit_id).one()

        # only owners can complete
        owner_ids = {member.id for member in audit.group.my_owners().values()}
        if user.id not in owner_ids:
            return self.forbidden()

        if audit.complete:
            return self.redirect("/groups/{}".format(audit.group.name))

        edges = {}
        for argument in self.request.arguments:
            if argument.startswith('audit_'):
                edges[int(argument.split('_')
                          [1])] = self.request.arguments[argument][0]

        for member in audit.my_members():
            if member.id in edges:
                # You can only approve yourself (otherwise you can remove yourself
                # from the group and leave it ownerless)
                if member.member.id == user.id:
                    member.status = "approved"
                elif edges[member.id] in AUDIT_STATUS_CHOICES:
                    member.status = edges[member.id]

        self.session.commit()

        # Now if it's completable (no pendings) then mark it complete, else redirect them
        # to the group page.
        if not audit.completable:
            return self.redirect('/groups/{}'.format(audit.group.name))

        # Complete audits have to be "enacted" now. This means anybody marked as remove has to
        # be removed from the group now.
        try:
            for member in audit.my_members():
                if member.status == "remove":
                    audit.group.revoke_member(self.current_user, member.member,
                                              "Revoked as part of audit.")
                    AuditLog.log(self.session,
                                 self.current_user.id,
                                 'remove_member',
                                 'Removed membership in audit: {}'.format(
                                     member.member.name),
                                 on_group_id=audit.group.id,
                                 on_user_id=member.member.id,
                                 category=AuditLogCategory.audit)
        except PluginRejectedGroupMembershipUpdate as e:
            alert = Alert("danger", str(e))
            return self.redirect('/groups/{}'.format(audit.group.name),
                                 alerts=[alert])

        audit.complete = True
        self.session.commit()

        # Now cancel pending emails
        cancel_async_emails(self.session, 'audit-{}'.format(audit.group.id))

        AuditLog.log(self.session,
                     self.current_user.id,
                     'complete_audit',
                     'Completed group audit.',
                     on_group_id=audit.group.id,
                     category=AuditLogCategory.audit)

        # check if all audits are complete
        if get_audits(self.session, only_open=True).count() == 0:
            AuditLog.log(self.session,
                         self.current_user.id,
                         'complete_global_audit',
                         'last open audit have been completed',
                         category=AuditLogCategory.audit)

        return self.redirect('/groups/{}'.format(audit.group.name))
示例#49
0
 def check_access_without_membership(session, actor, target):
     return (
         user_has_permission(session, actor, USER_ADMIN)
         or (target.role_user and is_owner_of_role_user(session, actor, tuser=target))
         or user_has_permission(session, actor, USER_ENABLE, argument=target.name)
     )
 def check_access(session, actor, target):
     if user_has_permission(session, actor, USER_ADMIN):
         return True
     return can_manage_service_account(session, target, actor)