Пример #1
0
    def edit_member(self, requester, user_or_group, reason, **kwargs):
        """ Edit an existing member (User or Group) of a group.

            This takes the same parameters as add_member, except that we do not allow you to set
            a status: this only works on existing members.

            Any option that is not passed is not updated, and instead, the existing value for this
            user is kept.
        """
        logging.debug(
            "Editing member (%s) in %s", user_or_group.name, self.groupname
        )

        persist_group_member_changes(
            session=self.session,
            group=self,
            requester=requester,
            member=user_or_group,
            status="actioned",
            reason=reason,
            **kwargs
        )

        member_type = user_or_group.member_type

        message = "Edit member {} {}: {}".format(
            OBJ_TYPES_IDX[member_type].lower(), user_or_group.name, reason)
        AuditLog.log(self.session, requester.id, 'edit_member',
                     message, on_group_id=self.id)
Пример #2
0
    def post(self, user_id=None, name=None, key_id=None, tag_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        try:
            key = get_public_key(self.session, user.id, key_id)
        except KeyNotFound:
            return self.notfound()

        tag = PublicKeyTag.get(self.session, id=tag_id)

        if not tag:
            return self.notfound()

        try:
            remove_tag_from_public_key(self.session, key, tag)
        except TagNotOnKey:
            return self.redirect("/users/{}?refresh=yes".format(user.name))

        AuditLog.log(
            self.session,
            self.current_user.id,
            "untag_public_key",
            "Untagged public key: {}".format(key.fingerprint_sha256),
            on_tag_id=tag.id,
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #3
0
def test_group_logdump(make_session, session, users, groups, tmpdir):
    make_session.return_value = session

    groupname = 'team-sre'
    group_id = groups[groupname].id

    yesterday = date.today() - timedelta(days=1)
    fn = tmpdir.join('out.csv').strpath

    call_main('group', 'log_dump', groupname, yesterday.isoformat(), '--outfile', fn)
    with open(fn, 'r') as fh:
        out = fh.read()

    assert not out, 'nothing yet'

    AuditLog.log(session, users['*****@*****.**'].id, 'make_noise', 'making some noise',
            on_group_id=group_id)
    session.commit()

    call_main('group', 'log_dump', groupname, yesterday.isoformat(), '--outfile', fn)
    with open(fn, 'r') as fh:
        entries = [x for x in csv.reader(fh)]

    assert len(entries) == 1, 'should capture our new audit log entry'

    log_time, actor, description, action, extra = entries[0]
    assert groupname in extra
Пример #4
0
def test_group_logdump(session, tmpdir, users, groups):  # noqa: F811
    groupname = "team-sre"
    group_id = groups[groupname].id

    yesterday = date.today() - timedelta(days=1)
    fn = tmpdir.join("out.csv").strpath

    call_main(session, tmpdir, "group", "log_dump", groupname,
              yesterday.isoformat(), "--outfile", fn)
    with open(fn, "r") as fh:
        out = fh.read()

    assert not out, "nothing yet"

    AuditLog.log(session,
                 users["*****@*****.**"].id,
                 "make_noise",
                 "making some noise",
                 on_group_id=group_id)
    session.commit()

    call_main(session, tmpdir, "group", "log_dump", groupname,
              yesterday.isoformat(), "--outfile", fn)
    with open(fn, "r") as fh:
        entries = [x for x in csv.reader(fh)]

    assert len(entries) == 1, "should capture our new audit log entry"

    log_time, actor, description, action, extra = entries[0]
    assert groupname in extra
Пример #5
0
    def post(self, group_id=None, name=None, account_id=None, accountname=None, mapping_id=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()
        service_account = ServiceAccount.get(self.session, account_id, accountname)
        if not service_account:
            return self.notfound()

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

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

        permission = mapping.permission
        argument = mapping.argument

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

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

        return self.redirect("/groups/{}/service/{}?refresh=yes".format(
            group.name, service_account.user.username))
Пример #6
0
    def post(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserShellForm(self.request.arguments)
        form.shell.choices = settings.shell
        if not form.validate():
            return self.render(
                "user-shell.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        user.set_metadata(USER_METADATA_SHELL_KEY, form.data["shell"])
        user.add(self.session)
        self.session.commit()

        AuditLog.log(self.session, self.current_user.id, 'changed_shell',
                     'Changed shell: {}'.format(form.data["shell"]),
                     on_user_id=user.id)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #7
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))
Пример #8
0
    def post(self, user_id=None, name=None):

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        try:
            if user.role_user:
                disable_role_user(self.session, user=user)
            else:
                disable_user(self.session, user)
        except PluginRejectedDisablingUser as e:
            alert = Alert("danger", str(e))
            return self.redirect("/users/{}".format(user.name), alerts=[alert])

        self.session.commit()

        AuditLog.log(
            self.session,
            self.current_user.id,
            "disable_user",
            "Disabled user.",
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #9
0
    def post(self, user_id=None, name=None, key_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        try:
            key = get_public_key(self.session, user.id, key_id)
            delete_public_key(self.session, user.id, key_id)
        except KeyNotFound:
            return self.notfound()

        AuditLog.log(self.session, self.current_user.id, 'delete_public_key',
                     'Deleted public key: {}'.format(key.fingerprint),
                     on_user_id=user.id)

        email_context = {
                "actioner": self.current_user.name,
                "changed_user": user.name,
                "action": "removed",
                }
        send_email(self.session, [user.name], 'Public SSH key removed', 'ssh_keys_changed',
                settings, email_context)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #10
0
    def post(self):
        form = TagCreateForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "tag-create.html", form=form, alerts=self.get_form_alerts(form.errors)
            )

        tag = PublicKeyTag(name=form.data["tagname"], description=form.data["description"])

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

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

        AuditLog.log(
            self.session, self.current_user.id, "create_tag", "Created new tag.", on_tag_id=tag.id
        )

        return self.redirect("/tags/{}?refresh=yes".format(tag.name))
Пример #11
0
    def edit_member(self, requester, user_or_group, reason, **kwargs):
        """ Edit an existing member (User or Group) of a group.

            This takes the same parameters as add_member, except that we do not allow you to set
            a status: this only works on existing members.

            Any option that is not passed is not updated, and instead, the existing value for this
            user is kept.
        """
        logging.debug("Editing member (%s) in %s", user_or_group.name,
                      self.groupname)

        persist_group_member_changes(session=self.session,
                                     group=self,
                                     requester=requester,
                                     member=user_or_group,
                                     status="actioned",
                                     reason=reason,
                                     **kwargs)

        member_type = user_or_group.member_type

        message = "Edit member {} {}: {}".format(
            OBJ_TYPES_IDX[member_type].lower(), user_or_group.name, reason)
        AuditLog.log(self.session,
                     requester.id,
                     "edit_member",
                     message,
                     on_group_id=self.id)
Пример #12
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserGitHubForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "user-github.html", form=form, user=user, alerts=self.get_form_alerts(form.errors)
            )

        new_username = form.data["username"]
        if new_username == "":
            new_username = None
        set_user_metadata(self.session, user.id, USER_METADATA_GITHUB_USERNAME_KEY, new_username)

        AuditLog.log(
            self.session,
            self.current_user.id,
            "changed_github_username",
            "Changed GitHub username: {}".format(form.data["username"]),
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #13
0
    def post(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")

        user = User.get(self.session, name=name)
        if not user:
            return self.notfound()

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

        form = UserShellForm(self.request.arguments)
        form.shell.choices = settings().shell
        if not form.validate():
            return self.render("user-shell.html",
                               form=form,
                               user=user,
                               alerts=self.get_form_alerts(form.errors))

        set_user_metadata(self.session, user.id, USER_METADATA_SHELL_KEY,
                          form.data["shell"])

        AuditLog.log(
            self.session,
            self.current_user.id,
            "changed_shell",
            "Changed shell: {}".format(form.data["shell"]),
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #14
0
    def post(self, name=None, mapping_id=None):
        grantable = self.current_user.my_grantable_permissions()
        if not grantable:
            return self.forbidden()

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

        allowed = False
        for perm in grantable:
            if perm[0].name == mapping.permission.name:
                if matches_glob(perm[1], mapping.argument):
                    allowed = True
        if not allowed:
            return self.forbidden()

        permission = mapping.permission
        group = mapping.group

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

        AuditLog.log(self.session, self.current_user.id, 'revoke_permission',
                     'Revoked permission with argument: {}'.format(mapping.argument),
                     on_group_id=group.id, on_permission_id=permission.id)

        return self.redirect('/groups/{}?refresh=yes'.format(group.name))
Пример #15
0
def disable_permission_auditing(session, permission_name, actor_user_id):
    """Set a permission as audited.

    Args:
        session(models.base.session.Session): database session
        permission_name(str): name of permission in question
        actor_user_id(int): id of user who is disabling auditing
    """
    permission = get_permission(session, permission_name)
    if not permission:
        raise NoSuchPermission(name=permission_name)

    permission.audited = False

    AuditLog.log(
        session,
        actor_user_id,
        "disable_auditing",
        "Disabled auditing.",
        on_permission_id=permission.id,
    )

    Counter.incr(session, "updates")

    session.commit()
Пример #16
0
def notify_nonauditor_promoted(settings, session, user, auditors_group, group_names):
    # type: (Settings, Session, User, Group, Set[str]) -> None
    """Send notification that a nonauditor has been promoted to be an auditor.

    Handles email notification and audit logging.

    Args:
        settings: Grouper Settings object for current run.
        session: Object for db session.
        user: The user that has been promoted.
        auditors_group: The auditors group
        group_names: The audited groups in which the user was previously a non-auditor approver.
    """
    member_name = user.username
    recipients = [member_name]
    auditors_group_name = auditors_group.groupname

    audit_data = {
        "action": "nonauditor_promoted",
        "actor_id": user.id,
        "description": "Added {} to group {}".format(member_name, auditors_group_name),
    }
    AuditLog.log(session, on_user_id=user.id, on_group_id=auditors_group.id, **audit_data)

    email_context = {"auditors_group_name": auditors_group_name, "member_name": member_name}
    send_email(
        session=session,
        recipients=recipients,
        subject='Added as member to group "{}"'.format(auditors_group_name),
        template="nonauditor_promoted",
        settings=settings,
        context=email_context,
    )
Пример #17
0
    def post(self, user_id=None, name=None, key_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        try:
            key = get_public_key(self.session, user.id, key_id)
            delete_public_key(self.session, user.id, key_id)
        except KeyNotFound:
            return self.notfound()

        AuditLog.log(self.session,
                     self.current_user.id,
                     'delete_public_key',
                     'Deleted public key: {}'.format(key.fingerprint_sha256),
                     on_user_id=user.id)

        email_context = {
            "actioner": self.current_user.name,
            "changed_user": user.name,
            "action": "removed",
        }
        send_email(self.session, [user.name], 'Public SSH key removed',
                   'ssh_keys_changed', settings, email_context)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #18
0
    def post(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")
        password_id = int(self.get_path_argument("password_id"))

        user = User.get(self.session, name=name)
        if not user:
            return self.notfound()

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

        password = UserPassword.get(self.session, user=user, id=password_id)

        try:
            delete_user_password(self.session, password.name, user.id)
        except PasswordDoesNotExist:
            # if the password doesn't exist, we can pretend like it did and that we deleted it
            return self.redirect("/users/{}?refresh=yes".format(user.username))
        AuditLog.log(
            self.session,
            self.current_user.id,
            "delete_password",
            "Deleted password: {}".format(password.name),
            on_user_id=user.id,
        )
        self.session.commit()
        return self.redirect("/users/{}?refresh=yes".format(user.username))
Пример #19
0
    def post(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserEnableForm(self.request.arguments)
        if not form.validate():
            # TODO: add error message
            return self.redirect("/users/{}?refresh=yes".format(user.name))

        if user.role_user:
            enable_service_account(self.session, actor=self.current_user,
                preserve_membership=form.preserve_membership.data, user=user)
        else:
            enable_user(self.session, user, self.current_user,
                preserve_membership=form.preserve_membership.data)

        self.session.commit()

        AuditLog.log(self.session, self.current_user.id, 'enable_user',
                     'Enabled user.', on_user_id=user.id)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #20
0
    def post(self, name=None, mapping_id=None):
        mapping = PermissionMap.get(self.session, id=mapping_id)

        if not mapping:
            return self.notfound()

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

        permission = mapping.permission
        group = mapping.group

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

        AuditLog.log(self.session,
                     self.current_user.id,
                     'revoke_permission',
                     'Revoked permission with argument: {}'.format(
                         mapping.argument),
                     on_group_id=group.id,
                     on_permission_id=permission.id)

        return self.redirect('/groups/{}?refresh=yes'.format(group.name))
Пример #21
0
def test_group_logdump(session, tmpdir, users, groups):  # noqa: F811
    groupname = "team-sre"
    group_id = groups[groupname].id

    yesterday = date.today() - timedelta(days=1)
    fn = tmpdir.join("out.csv").strpath

    call_main(
        session, tmpdir, "group", "log_dump", groupname, yesterday.isoformat(), "--outfile", fn
    )
    with open(fn, "r") as fh:
        out = fh.read()

    assert not out, "nothing yet"

    AuditLog.log(
        session, users["*****@*****.**"].id, "make_noise", "making some noise", on_group_id=group_id
    )
    session.commit()

    call_main(
        session, tmpdir, "group", "log_dump", groupname, yesterday.isoformat(), "--outfile", fn
    )
    with open(fn, "r") as fh:
        entries = [x for x in csv.reader(fh)]

    assert len(entries) == 1, "should capture our new audit log entry"

    log_time, actor, description, action, extra = entries[0]
    assert groupname in extra
Пример #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 self.current_user.can_manage(group):
            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."
            )

        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)
        return self.redirect("/groups/{}?refresh=yes".format(group.name))
Пример #23
0
def create_service_account(session, actor, name, description, machine_set, owner):
    # type: (Session, User, str, str, str, Group) -> ServiceAccount
    """Creates a service account and its underlying user.

    Also adds the service account to the list of accounts managed by the owning group.

    Throws:
        BadMachineSet: if some plugin rejected the machine set
        DuplicateServiceAccount: if a user with the given name already exists
    """
    user = User(username=name, is_service_account=True)
    service_account = ServiceAccount(user=user, description=description, machine_set=machine_set)

    if machine_set is not None:
        _check_machine_set(service_account, machine_set)

    try:
        user.add(session)
        service_account.add(session)
        session.flush()
    except IntegrityError:
        session.rollback()
        raise DuplicateServiceAccount("User {} already exists".format(name))

    # Counter is updated here and the session is committed, so we don't need an additional update
    # or commit for the account creation.
    add_service_account(session, owner, service_account)

    AuditLog.log(session, actor.id, "create_service_account", "Created new service account.",
                 on_group_id=owner.id, on_user_id=service_account.user_id)

    return service_account
Пример #24
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))
Пример #25
0
    def post(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserEnableForm(self.request.arguments)
        if not form.validate():
            # TODO: add error message
            return self.redirect("/users/{}?refresh=yes".format(user.name))

        if user.role_user:
            enable_service_account(
                self.session,
                actor=self.current_user,
                preserve_membership=form.preserve_membership.data,
                user=user)
        else:
            enable_user(self.session,
                        user,
                        self.current_user,
                        preserve_membership=form.preserve_membership.data)

        self.session.commit()

        AuditLog.log(self.session,
                     self.current_user.id,
                     'enable_user',
                     'Enabled user.',
                     on_user_id=user.id)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #26
0
def create_role_user(session, actor, name, description, canjoin):
    # type (Session, User, str, str, str) -> None
    """DEPRECATED: Do not use in production code

    Creates a service account with the given name, description, and canjoin status

    Args:
        session: the database session
        actor: the user creating the service account
        name: the name of the service account
        description: description of the service account
        canjoin: the canjoin status for management of the service account

    Throws:
        IntegrityError: if a user or group with the given name already exists
    """
    user = User(username=name, role_user=True)
    group = Group(groupname=name, description=description, canjoin=canjoin)

    user.add(session)
    group.add(session)

    group.add_member(actor, actor, "Group Creator", "actioned", None, "np-owner")
    group.add_member(actor, user, "Service Account", "actioned", None, "member")
    session.commit()

    AuditLog.log(
        session,
        actor.id,
        "create_role_user",
        "Created new service account.",
        on_group_id=group.id,
        on_user_id=user.id,
    )
Пример #27
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))
Пример #28
0
def test_group_logdump(make_session, session, users, groups, tmpdir):
    make_session.return_value = session

    groupname = 'team-sre'
    group_id = groups[groupname].id

    yesterday = date.today() - timedelta(days=1)
    fn = tmpdir.join('out.csv').strpath

    call_main('group', 'log_dump', groupname, yesterday.isoformat(),
              '--outfile', fn)
    with open(fn, 'r') as fh:
        out = fh.read()

    assert not out, 'nothing yet'

    AuditLog.log(session,
                 users['*****@*****.**'].id,
                 'make_noise',
                 'making some noise',
                 on_group_id=group_id)
    session.commit()

    call_main('group', 'log_dump', groupname, yesterday.isoformat(),
              '--outfile', fn)
    with open(fn, 'r') as fh:
        entries = [x for x in csv.reader(fh)]

    assert len(entries) == 1, 'should capture our new audit log entry'

    log_time, actor, description, action, extra = entries[0]
    assert groupname in extra
    def post(self, group_id=None, name=None, account_id=None, accountname=None, mapping_id=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()
        service_account = ServiceAccount.get(self.session, account_id, accountname)
        if not service_account:
            return self.notfound()

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

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

        permission = mapping.permission
        argument = mapping.argument

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

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

        return self.redirect(
            "/groups/{}/service/{}?refresh=yes".format(group.name, service_account.user.username)
        )
Пример #30
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))
Пример #31
0
def disable_permission_auditing(session: Session, permission_name: str,
                                actor_user_id: int) -> None:
    """Set a permission as audited.

    Args:
        session: Database session
        permission_name: Name of permission in question
        actor_user_id: ID of user who is disabling auditing
    """
    permission = get_permission(session, permission_name)
    if not permission:
        raise NoSuchPermission(name=permission_name)

    permission.audited = False

    AuditLog.log(
        session,
        actor_user_id,
        "disable_auditing",
        "Disabled auditing.",
        on_permission_id=permission.id,
    )

    Counter.incr(session, "updates")

    session.commit()
Пример #32
0
    def post(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserPasswordForm(self.request.arguments)
        if not form.validate():
            return self.render("user-password-add.html", form=form, user=user, alerts=self.get_form_alerts(form.errors))

        pass_name = form.data["name"]
        password = form.data["password"]
        try:
            add_new_user_password(self.session, pass_name, password, user.id)
        except PasswordAlreadyExists:
            self.session.rollback()
            form.name.errors.append("Name already in use.")
            return self.render("user-password-add.html", form=form, user=user, alerts=self.get_form_alerts(form.errors))

        AuditLog.log(
            self.session,
            self.current_user.id,
            "add_password",
            "Added password: {}".format(pass_name),
            on_user_id=user.id,
        )

        email_context = {"actioner": self.current_user.name, "changed_user": user.name, "pass_name": pass_name}
        send_email(self.session, [user.name], "User password created", "user_password_created", settings, email_context)
        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #33
0
def disable_permission_auditing(session, permission_name, actor_user_id):
    """Set a permission as audited.

    Args:
        session(models.base.session.Session): database session
        permission_name(str): name of permission in question
        actor_user_id(int): id of user who is disabling auditing
    """
    permission = get_permission(session, permission_name)
    if not permission:
        raise NoSuchPermission(name=permission_name)

    permission._audited = False

    AuditLog.log(
        session,
        actor_user_id,
        "disable_auditing",
        "Disabled auditing.",
        on_permission_id=permission.id,
    )

    Counter.incr(session, "updates")

    session.commit()
Пример #34
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))
Пример #35
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_service_account(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))
Пример #36
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserGitHubForm(self.request.arguments)
        if not form.validate():
            return self.render("user-github.html",
                               form=form,
                               user=user,
                               alerts=self.get_form_alerts(form.errors))

        new_username = form.data["username"]
        if new_username == "":
            new_username = None
        set_user_metadata(self.session, user.id,
                          USER_METADATA_GITHUB_USERNAME_KEY, new_username)

        AuditLog.log(
            self.session,
            self.current_user.id,
            "changed_github_username",
            "Changed GitHub username: {}".format(form.data["username"]),
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #37
0
    def post(self, *args: Any, **kwargs: Any) -> None:
        mapping_id = int(self.get_path_argument("mapping_id"))
        mapping = PermissionMap.get(self.session, id=mapping_id)

        if not mapping:
            return self.notfound()

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

        permission = mapping.permission
        group = mapping.group

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

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

        return self.redirect("/groups/{}?refresh=yes".format(group.name))
Пример #38
0
def notify_nonauditor_flagged(settings, session, edge):
    """Send notification that a nonauditor in an audited group has had their membership
    set to expire.

    Handles email notification and audit logging.

    Args:
        settings (Settings): Grouper Settings object for current run.
        session (Session): Object for db session.
        edge (GroupEdge): The expiring edge.
    """
    # Pull data about the edge and the affected user
    group_name = edge.group.name
    assert OBJ_TYPES_IDX[edge.member_type] == "User"
    user = User.get(session, pk=edge.member_pk)
    member_name = user.username
    recipients = [member_name]

    audit_data = {
        "action": "nonauditor_flagged",
        "actor_id": user.id,
        "description": "Flagged {} as nonauditor approver in audited group".format(member_name),
    }
    AuditLog.log(session, on_user_id=user.id, on_group_id=edge.group_id, **audit_data)

    email_context = {"group_name": group_name, "member_name": member_name}
    send_email(
        session=session,
        recipients=recipients,
        subject="Membership in {} set to expire".format(group_name),
        template="nonauditor",
        settings=settings,
        context=email_context,
    )
Пример #39
0
def create_role_user(session, actor, name, description, canjoin):
    # type (Session, User, str, str, str) -> None
    """DEPRECATED: Do not use in production code

    Creates a service account with the given name, description, and canjoin status

    Args:
        session: the database session
        actor: the user creating the service account
        name: the name of the service account
        description: description of the service account
        canjoin: the canjoin status for management of the service account

    Throws:
        IntegrityError: if a user or group with the given name already exists
    """
    user = User(username=name, role_user=True)
    group = Group(groupname=name, description=description, canjoin=canjoin)

    user.add(session)
    group.add(session)

    group.add_member(actor, actor, "Group Creator", "actioned", None, "np-owner")
    group.add_member(actor, user, "Service Account", "actioned", None, "member")
    session.commit()

    AuditLog.log(
        session,
        actor.id,
        "create_role_user",
        "Created new service account.",
        on_group_id=group.id,
        on_user_id=user.id,
    )
Пример #40
0
    def post(self, user_id=None, name=None):

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        try:
            if user.role_user:
                disable_role_user(self.session, user=user)
            else:
                disable_user(self.session, user)
        except PluginRejectedDisablingUser as e:
            alert = Alert("danger", str(e))
            return self.redirect("/users/{}".format(user.name), alerts=[alert])

        self.session.commit()

        AuditLog.log(self.session,
                     self.current_user.id,
                     'disable_user',
                     'Disabled user.',
                     on_user_id=user.id)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #41
0
    def post(self, user_id=None, name=None, key_id=None, tag_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        try:
            key = get_public_key(self.session, user.id, key_id)
        except KeyNotFound:
            return self.notfound()

        tag = PublicKeyTag.get(self.session, id=tag_id)

        if not tag:
            return self.notfound()

        try:
            remove_tag_from_public_key(self.session, key, tag)
        except TagNotOnKey:
            return self.redirect("/users/{}?refresh=yes".format(user.name))

        AuditLog.log(self.session, self.current_user.id, 'untag_public_key',
                     'Untagged public key: {}'.format(key.fingerprint),
                     on_tag_id=tag.id, on_user_id=user.id)

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #42
0
    def post(self):
        form = TagCreateForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "tag-create.html", form=form,
                alerts=self.get_form_alerts(form.errors)
            )

        tag = PublicKeyTag(
            name=form.data["tagname"],
            description=form.data["description"],
        )

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

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

        AuditLog.log(self.session, self.current_user.id, 'create_tag',
                     'Created new tag.', on_tag_id=tag.id)

        return self.redirect("/tags/{}?refresh=yes".format(tag.name))
Пример #43
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserShellForm(self.request.arguments)
        form.shell.choices = settings().shell
        if not form.validate():
            return self.render(
                "user-shell.html", form=form, user=user, alerts=self.get_form_alerts(form.errors)
            )

        set_user_metadata(self.session, user.id, USER_METADATA_SHELL_KEY, form.data["shell"])

        AuditLog.log(
            self.session,
            self.current_user.id,
            "changed_shell",
            "Changed shell: {}".format(form.data["shell"]),
            on_user_id=user.id,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #44
0
    def post(self, user_id=None, name=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = PublicKeyForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "public-key-add.html",
                form=form,
                user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        try:
            pubkey = public_key.add_public_key(self.session, user,
                                               form.data["public_key"])
        except public_key.DuplicateKey:
            form.public_key.errors.append(
                "Key already in use. Public keys must be unique.")
        except public_key.PublicKeyParseError:
            form.public_key.errors.append("Public key appears to be invalid.")
        except public_key.BadPublicKey as e:
            form.public_key.errors.append(str(e))

        if form.public_key.errors:
            return self.render(
                "public-key-add.html",
                form=form,
                user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(
            self.session,
            self.current_user.id,
            "add_public_key",
            "Added public key: {}".format(pubkey.fingerprint_sha256),
            on_user_id=user.id,
        )

        email_context = {
            "actioner": self.current_user.name,
            "changed_user": user.name,
            "action": "added",
        }
        send_email(
            self.session,
            [user.name],
            "Public SSH key added",
            "ssh_keys_changed",
            settings,
            email_context,
        )

        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #45
0
    def post(self):
        can_create = user_creatable_permissions(self.session,
                                                self.current_user)
        if not can_create:
            return self.forbidden()

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

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

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

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

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

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

        self.session.commit()

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

        # No explicit refresh because handler queries SQL.
        return self.redirect("/permissions/{}".format(permission.name))
Пример #46
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserTokenForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "user-token-add.html",
                form=form,
                user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        try:
            token, secret = add_new_user_token(
                self.session, UserToken(name=form.data["name"], user=user))
            self.session.commit()
        except IntegrityError:
            self.session.rollback()
            form.name.errors.append("Name already in use.")
            return self.render(
                "user-token-add.html",
                form=form,
                user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(
            self.session,
            self.current_user.id,
            "add_token",
            "Added token: {}".format(token.name),
            on_user_id=user.id,
        )

        email_context = {
            "actioner": self.current_user.name,
            "changed_user": user.name,
            "action": "added",
        }
        send_email(
            self.session,
            [user.name],
            "User token created",
            "user_tokens_changed",
            settings(),
            email_context,
        )
        return self.render("user-token-created.html",
                           token=token,
                           secret=secret)
Пример #47
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserTokenForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "user-token-add.html",
                form=form,
                user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        try:
            token, secret = add_new_user_token(
                self.session, UserToken(name=form.data["name"], user=user)
            )
            self.session.commit()
        except IntegrityError:
            self.session.rollback()
            form.name.errors.append("Name already in use.")
            return self.render(
                "user-token-add.html",
                form=form,
                user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(
            self.session,
            self.current_user.id,
            "add_token",
            "Added token: {}".format(token.name),
            on_user_id=user.id,
        )

        email_context = {
            "actioner": self.current_user.name,
            "changed_user": user.name,
            "action": "added",
        }
        send_email(
            self.session,
            [user.name],
            "User token created",
            "user_tokens_changed",
            settings(),
            email_context,
        )
        return self.render("user-token-created.html", token=token, secret=secret)
Пример #48
0
    def post(self):
        can_create = user_creatable_permissions(self.session, self.current_user)
        if not can_create:
            return self.forbidden()

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

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

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

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

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

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

        self.session.commit()

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

        # No explicit refresh because handler queries SQL.
        return self.redirect("/permissions/{}".format(permission.name))
Пример #49
0
    def post(self, *args, **kwargs):
        # type: (*Any, **Any) -> None
        user_id = kwargs.get("user_id")  # type: Optional[int]
        name = kwargs.get("name")  # type: Optional[str]

        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

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

        form = UserPasswordForm(self.request.arguments)
        if not form.validate():
            return self.render(
                "user-password-add.html",
                form=form,
                user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        pass_name = form.data["name"]
        password = form.data["password"]
        try:
            add_new_user_password(self.session, pass_name, password, user.id)
        except PasswordAlreadyExists:
            self.session.rollback()
            form.name.errors.append("Name already in use.")
            return self.render(
                "user-password-add.html",
                form=form,
                user=user,
                alerts=self.get_form_alerts(form.errors),
            )

        AuditLog.log(
            self.session,
            self.current_user.id,
            "add_password",
            "Added password: {}".format(pass_name),
            on_user_id=user.id,
        )

        email_context = {
            "actioner": self.current_user.name,
            "changed_user": user.name,
            "pass_name": pass_name,
        }
        send_email(
            self.session,
            [user.name],
            "User password created",
            "user_password_created",
            settings(),
            email_context,
        )
        return self.redirect("/users/{}?refresh=yes".format(user.name))
Пример #50
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)
    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()
        user = service_account.user

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

        grantable = group.my_permissions()
        form = self.get_form(grantable)
        if not form.validate():
            return self.render(
                "service-account-permission-grant.html", form=form, user=user, group=group,
                alerts=self.get_form_alerts(form.errors)
            )

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

        allowed = False
        for perm in grantable:
            if perm[1] == permission.name:
                if matches_glob(perm[3], form.data["argument"]):
                    allowed = True
                    break
        if not allowed:
            form.argument.errors.append(
                "The group {} does not have that permission".format(group.name))
            return self.render(
                "service-account-permission-grant.html", form=form, user=user, group=group,
                alerts=self.get_form_alerts(form.errors)
            )

        try:
            grant_permission_to_service_account(
                self.session, service_account, permission, form.data["argument"])
        except IntegrityError:
            self.session.rollback()
            return self.render(
                "service-account-permission-grant.html", form=form, user=user,
                alerts=self.get_form_alerts(form.errors)
            )

        AuditLog.log(self.session, self.current_user.id, "grant_permission",
                     "Granted permission with argument: {}".format(form.data["argument"]),
                     on_permission_id=permission.id, on_group_id=group.id,
                     on_user_id=service_account.user.id)

        return self.redirect("/groups/{}/service/{}?refresh=yes".format(
            group.name, service_account.user.username))
Пример #52
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))
Пример #53
0
def enable_service_account(session, actor, service_account, owner):
    # type: (Session, User, ServiceAccount, Group) -> None
    """Enables a service account and sets a new owner."""
    enable_user(session, service_account.user, actor, preserve_membership=False)
    add_service_account(session, owner, service_account)

    AuditLog.log(session, actor.id, "enable_service_account", "Enabled service account.",
                 on_group_id=owner.id, on_user_id=service_account.user_id)

    Counter.incr(session, "updates")
    session.commit()
Пример #54
0
    def post(self, user_id=None, name=None, token_id=None):
        user = User.get(self.session, user_id, name)
        if not user:
            return self.notfound()

        if (user.name != self.current_user.name) and not self.current_user.user_admin:
            return self.forbidden()

        token = UserToken.get(self.session, user=user, id=token_id)
        disable_user_token(self.session, token)
        AuditLog.log(self.session, self.current_user.id, 'disable_token',
                     'Disabled token: {}'.format(token.name),
                     on_user_id=user.id)
        self.session.commit()
        return self.render("user-token-disabled.html", token=token)
Пример #55
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 self.current_user.my_role(members) in ("owner", "np-owner"):
            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))
Пример #56
0
def disable_service_account(session, actor, service_account):
    # type: (Session, User, ServiceAccount) -> None
    """Disables a service account and deletes the association with a Group."""
    disable_user(session, service_account.user)
    owner_id = service_account.owner.group.id
    service_account.owner.delete(session)
    permissions = session.query(ServiceAccountPermissionMap).filter_by(
        service_account_id=service_account.id)
    for permission in permissions:
        permission.delete(session)

    AuditLog.log(session, actor.id, "disable_service_account", "Disabled service account.",
                 on_group_id=owner_id, on_user_id=service_account.user_id)

    Counter.incr(session, "updates")
    session.commit()
Пример #57
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):
            return self.forbidden()

        group.revoke_member(self.current_user, self.current_user, "User self-revoked.")

        AuditLog.log(self.session, self.current_user.id, 'leave_group',
                     '{} left the group.'.format(self.current_user.name),
                     on_group_id=group.id)

        return self.redirect("/groups/{}?refresh=yes".format(group.name))