예제 #1
0
파일: user.py 프로젝트: santoshankr/grouper
def disable_user(session, user):
    """Disables an enabled user"""

    get_plugin_proxy().will_disable_user(session, user)

    user.enabled = False
    Counter.incr(session, "updates")
    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)
        )
예제 #3
0
    def update_status(self, requester, status, reason):
        now = datetime.utcnow()
        current_status = self.status
        self.status = status

        request_status_change = RequestStatusChange(
            request=self,
            user_id=requester.id,
            from_status=current_status,
            to_status=status,
            change_at=now
        ).add(self.session)
        self.session.flush()

        Comment(
            obj_type=OBJ_TYPES_IDX.index("RequestStatusChange"),
            obj_pk=request_status_change.id,
            user_id=requester.id,
            comment=reason,
            created_on=now
        ).add(self.session)

        if status == "actioned":
            edge = self.session.query(GroupEdge).filter_by(
                id=self.edge_id
            ).one()
            edge.apply_changes(self)

        Counter.incr(self.session, "updates")
예제 #4
0
    def set_metadata(self, key, value):
        if not re.match(PERMISSION_VALIDATION, key):
            raise ValueError('Metadata key does not match regex.')

        row = None
        for try_row in self.my_metadata():
            if try_row.data_key == key:
                row = try_row
                break

        if row:
            if value is None:
                row.delete(self.session)
            else:
                row.data_value = value
        else:
            if value is None:
                # Do nothing, a delete on a key that's not set
                return
            else:
                row = UserMetadata(user_id=self.id, data_key=key, data_value=value)
                row.add(self.session)

        Counter.incr(self.session, "updates")
        self.session.commit()
예제 #5
0
파일: tag_edit.py 프로젝트: Acidity/grouper
    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))
예제 #6
0
def add_public_key(session, user, public_key_str):
    """Add a public key for a particular user.

    Args:
        session: db session
        user: User model of user in question
        public_key_str: public key to add

    Return created PublicKey model or raises DuplicateKey if key is already in use.
    """
    pubkey = sshpubkey.PublicKey.from_str(public_key_str)
    db_pubkey = PublicKey(
        user=user,
        public_key='%s %s %s' % (pubkey.key_type, pubkey.key, pubkey.comment),
        fingerprint=pubkey.fingerprint,
        key_size=pubkey.key_size,
        key_type=pubkey.key_type,
    )
    try:
        db_pubkey.add(session)
        Counter.incr(session, "updates")
    except IntegrityError:
        session.rollback()
        raise DuplicateKey()

    session.commit()

    return db_pubkey
예제 #7
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))
예제 #8
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()
예제 #9
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))
예제 #10
0
def grant_permission_to_tag(session, tag_id, permission_id, argument=''):
    # type: (Session, int, int, str) -> bool
    """
    Grant a permission to this tag. This will fail if the (permission, argument) has already
    been granted to this tag.

    Args:
        session(models.base.session.Sessioan): database session
        tag_id(int): the id of the tag we're granting the permission to
        permission_id(int): the id of the permission to be granted
        argument(str): must match constants.ARGUMENT_VALIDATION

    Throws:
        AssertError if argument does not match ARGUMENT_VALIDATION regex

    Returns:
        bool indicating whether the function succeeded or not
    """
    assert re.match(ARGUMENT_VALIDATION + r"$", argument), \
        'Permission argument does not match regex.'

    try:
        mapping = TagPermissionMap(permission_id=permission_id, tag_id=tag_id, argument=argument)
        mapping.add(session)

        Counter.incr(session, "updates")
    except IntegrityError:
        session.rollback()
        return False

    session.commit()
    return True
예제 #11
0
def grant_permission_to_service_account(session, account, permission, argument=""):
    """
    Grant a permission to this service account. This will fail if the (permission, argument) has
    already been granted to this group.

    Args:
        session(models.base.session.Session): database session
        account(ServiceAccount): a ServiceAccount object being granted a permission
        permission(Permission): a Permission object being granted
        argument(str): must match constants.ARGUMENT_VALIDATION

    Throws:
        AssertError if argument does not match ARGUMENT_VALIDATION regex
    """
    assert re.match(
        ARGUMENT_VALIDATION + r"$", argument
    ), "Permission argument does not match regex."

    mapping = ServiceAccountPermissionMap(
        permission_id=permission.id, service_account_id=account.id, argument=argument
    )
    mapping.add(session)

    Counter.incr(session, "updates")

    session.commit()
예제 #12
0
def add_service_account(session, group, service_account):
    # type: (Session, Group, ServiceAccount) -> None
    """Add a service account to a group."""
    logging.debug("Adding service account %s to %s", service_account.user.username,
        group.groupname)
    GroupServiceAccount(group_id=group.id, service_account=service_account).add(session)
    Counter.incr(session, "updates")
    session.commit()
예제 #13
0
    def revoke_member(self, requester, user_or_group, reason):
        """ Revoke a member (User or Group) from this group.

            Arguments:
                requester: A User object of the person requesting the addition
                user_or_group: A User/Group object of the member
                reason: A comment on why this member should exist
        """
        now = datetime.utcnow()

        logging.debug(
            "Revoking member (%s) from %s", user_or_group.name, self.groupname
        )

        # Create the edge even if it doesn't exist so that we can explicitly
        # disable it.
        edge, new = GroupEdge.get_or_create(
            self.session,
            group_id=self.id,
            member_type=user_or_group.member_type,
            member_pk=user_or_group.id,
        )
        self.session.flush()

        request = Request(
            requester_id=requester.id,
            requesting_id=self.id,
            on_behalf_obj_type=user_or_group.member_type,
            on_behalf_obj_pk=user_or_group.id,
            requested_at=now,
            edge_id=edge.id,
            status="actioned",
            changes=build_changes(
                edge, role="member", expiration=None, active=False
            )
        ).add(self.session)
        self.session.flush()

        request_status_change = RequestStatusChange(
            request=request,
            user_id=requester.id,
            to_status="actioned",
            change_at=now
        ).add(self.session)
        self.session.flush()

        Comment(
            obj_type=OBJ_TYPES_IDX.index("RequestStatusChange"),
            obj_pk=request_status_change.id,
            user_id=requester.id,
            comment=reason,
            created_on=now
        ).add(self.session)

        edge.apply_changes(request)
        self.session.flush()

        Counter.incr(self.session, "updates")
예제 #14
0
def disable_user_token(session, user_token):
    """Disable specified user token.

    Args:
        session(grouper.models.base.session.Session): database session
        user_token(grouper.models.user_token.UserToken): token to disable
    """
    user_token.disabled_at = datetime.utcnow()
    Counter.incr(session, "updates")
예제 #15
0
def persist_group_member_changes(session, group, requester, member, status, reason,
                                 create_edge=False, **updates):
    requested_at = datetime.utcnow()

    if "role" in updates:
        role = updates["role"]
        _validate_role(member.member_type, role)

    get_plugin_proxy().will_update_group_membership(session, group, member, **updates)

    if create_edge:
        edge = _create_edge(session, group, member, updates.get("role", "member"))
    else:
        edge = _get_edge(session, group, member)
        if not edge:
            raise MemberNotFound()

    changes = _serialize_changes(edge, **updates)

    request = Request(
        requester_id=requester.id,
        requesting_id=group.id,
        on_behalf_obj_type=member.member_type,
        on_behalf_obj_pk=member.id,
        requested_at=requested_at,
        edge_id=edge.id,
        status=status,
        changes=changes,
    ).add(session)
    session.flush()

    request_status_change = RequestStatusChange(
        request=request,
        user_id=requester.id,
        to_status=status,
        change_at=requested_at,
    ).add(session)
    session.flush()

    Comment(
        obj_type=OBJ_TYPES["RequestStatusChange"],
        obj_pk=request_status_change.id,
        user_id=requester.id,
        comment=reason,
        created_on=requested_at,
    ).add(session)
    session.flush()

    if status == "actioned":
        edge.apply_changes(request.changes)
        session.flush()

    Counter.incr(session, "updates")

    return request
예제 #16
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()
예제 #17
0
def test_groups_email(groups, session, graph, http_client, base_url):  # noqa: F811
    expected_address = "*****@*****.**"
    sad = groups["sad-team"]
    sad.email_address = expected_address
    session.commit()
    Counter.incr(session, "updates")
    graph.update_from_db(session)

    api_url = url(base_url, "/groups/{}".format(sad.name))
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    assert body["data"]["group"]["contacts"]["email"] == expected_address
예제 #18
0
def delete_public_key(session, user_id, key_id):
    """Delete a particular user's public key.

    Args:
        session(models.base.session.Session): database session
        user_id(int): id of user in question
        key_id(int): id of the user's key we want to delete

    Throws:
        KeyNotFound if specified key wasn't found
    """
    pkey = get_public_key(session, user_id, key_id)
    pkey.delete(session)
    Counter.incr(session, "updates")
    session.commit()
예제 #19
0
def delete_user_password(session, password_name, user_id):
    # type: (Session, str, int) -> None
    """Delete the specified UserPassword.

    Args:
        session(grouper.models.base.session.Session): database session
        password_name: the name of the password to delete
        user_id: the user whose password is being deleted
    """
    p = session.query(UserPassword).filter_by(name=password_name, user_id=user_id).scalar()
    if not p:
        raise PasswordDoesNotExist()
    p.delete(session)
    Counter.incr(session, "updates")
    session.commit()
예제 #20
0
def add_public_key(session, user, public_key_str):
    """Add a public key for a particular user.

    Args:
        session: db session
        user: User model of user in question
        public_key_str: public key to add

    Throws:
        DuplicateKey if key is already in use
        PublicKeyParseError if key can't be parsed
        BadPublicKey if a plugin rejects the key

    Returns:
        PublicKey model object representing the key
    """
    pubkey = sshpubkeys.SSHKey(public_key_str, strict=True)

    try:
        pubkey.parse()
    except sshpubkeys.InvalidKeyException as e:
        raise PublicKeyParseError(str(e))

    try:
        get_plugin_proxy().will_add_public_key(pubkey)
    except PluginRejectedPublicKey as e:
        raise BadPublicKey(str(e))

    db_pubkey = PublicKey(
        user=user,
        public_key=pubkey.keydata.strip(),
        fingerprint=pubkey.hash_md5().replace("MD5:", ""),
        fingerprint_sha256=pubkey.hash_sha256().replace("SHA256:", ""),
        key_size=pubkey.bits,
        key_type=pubkey.key_type,
        comment=pubkey.comment,
    )

    try:
        db_pubkey.add(session)
        Counter.incr(session, "updates")
    except IntegrityError:
        session.rollback()
        raise DuplicateKey()

    session.commit()

    return db_pubkey
예제 #21
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()
예제 #22
0
    def post(self, group_id=None, name=None):
        group = Group.get(self.session, group_id, name)
        if not group:
            return self.notfound()

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

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

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

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

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

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

        return self.redirect("/groups/{}".format(group.name))
예제 #23
0
def add_new_user_password(session, password_name, password, user_id):
    # type: (Session, str, str, int) -> None
    """Add the new user password specified.

    Args:
        session(grouper.models.base.session.Session): database session
        password_name(str): name of the password to be added
        password(str): the (plaintext) password to be added
        user_id(int): the id of the user to add this password to
    """
    p = UserPassword(name=password_name, user_id=user_id)
    p.set_password(password)
    Counter.incr(session, "updates")
    p.add(session)
    try:
        session.commit()
    except IntegrityError:
        raise PasswordAlreadyExists()
예제 #24
0
def edit_service_account(session, actor, service_account, description, machine_set):
    # type: (Session, User, ServiceAccount, str, str) -> None
    """Update the description and machine set of a service account.

    Raises:
        PluginRejectedMachineSet: if some plugin rejected the machine set
    """
    if machine_set is not None:
        _check_machine_set(service_account, machine_set)

    service_account.description = description
    service_account.machine_set = machine_set
    Counter.incr(session, "updates")

    session.commit()

    AuditLog.log(session, actor.id, "edit_service_account", "Edited service account.",
                 on_user_id=service_account.user.id)
예제 #25
0
def add_new_user_token(session, user_token):
    """Add the new user token specified. If user token doesn't contain a
    secret, create one.

    Args:
        session(grouper.models.base.session.Session): database session
        user_token(grouper.models.user_token.UserToken): token to create

    Returns:
        2-tuple of the created UserToken and the secret
    """
    secret = None
    if user_token.hashed_secret is None:
        secret = user_token._set_secret()

    user_token.add(session)
    Counter.incr(session, "updates")

    return user_token, secret
예제 #26
0
def test_users_aliased_permissions(
    mocker, session, standard_graph, http_client, base_url  # noqa: F811
):
    proxy = PluginProxy([PermissionAliasesPlugin()])
    mocker.patch("grouper.graph.get_plugin_proxy", return_value=proxy)

    # Force graph update
    Counter.incr(session, "updates")
    standard_graph.update_from_db(session)

    api_url = url(base_url, "/users/[email protected]")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    perms = [(p["permission"], p["argument"]) for p in body["data"]["permissions"]]

    assert ("owner", "sad-team") in perms
    assert ("ssh", "owner=sad-team") in perms
    assert ("sudo", "sad-team") in perms
예제 #27
0
def test_permissions_aliased_permissions(mocker, session, standard_graph, http_client, base_url):
    proxy = PluginProxy([PermissionAliasesPlugin()])
    mocker.patch('grouper.graph.get_plugin_proxy', return_value=proxy)

    # Force graph update
    Counter.incr(session, "updates")
    standard_graph.update_from_db(session)

    api_url = url(base_url, '/permissions/ssh')
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    permissions = [
        (group, p['argument'])
        for group, g in body['data']['groups'].iteritems()
        for p in g['permissions']
    ]

    assert ('sad-team', 'owner=sad-team') in permissions
예제 #28
0
def enable_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 enabling auditing
    """
    permission = Permission.get(session, permission_name)
    if not permission:
        raise NoSuchPermission(name=permission_name)

    permission._audited = True

    AuditLog.log(session, actor_user_id, 'enable_auditing', 'Enabled auditing.',
            on_permission_id=permission.id)

    Counter.incr(session, "updates")

    session.commit()
예제 #29
0
def add_tag_to_public_key(session, public_key, tag):
    # type: (Session, PublicKey, PublicKeyTag) -> None
    """Assigns the tag to the given public key.

    Args:
        session(models.base.session.Session): database session
        public_key(models.public_key.PublicKey): the public key to be tagged
        tag(models.public_key_tag.PublicKeyTag): the tag to be assigned to the public key

    Throws:
        DuplicateTag if the tag was already assigned to the public key
    """
    mapping = PublicKeyTagMap(tag_id=tag.id, key_id=public_key.id)
    try:
        mapping.add(session)
        Counter.incr(session, "updates")
        session.commit()
    except IntegrityError:
        session.rollback()
        raise DuplicateTag()
예제 #30
0
def remove_tag_from_public_key(session, public_key, tag):
    # type: (Session, PublicKey, PublicKeyTag) -> None
    """Removes the tag from the given public key.

    Args:
        session(models.base.session.Session): database session
        public_key(models.public_key.PublicKey): the public key to be tagged
        tag(models.public_key_tag.PublicKeyTag): the tag to be removed from the public key

    Throws:
        TagNotOnKey if the tag was already assigned to the public key
    """
    mapping = session.query(PublicKeyTagMap).filter_by(tag_id=tag.id, key_id=public_key.id).scalar()

    if not mapping:
        raise TagNotOnKey()

    mapping.delete(session)
    Counter.incr(session, "updates")
    session.commit()
예제 #31
0
def set_user_metadata(session, user_id, data_key, data_value):
    # type: (Session, int, str, str) -> Optional[UserMetadata]
    """Set a single piece of user metadata.

    Args:
        session(models.base.session.Session): database session
        user_id(int): id of user in question
        data_key(str): the metadata key (limited to 64 character by db schema)
        data_value(str):  the metadata value (limited to 64 character by db
                schema) if this is None, the metadata entry is deleted.

    Returns:
        the UserMetadata object or None if entry was deleted
    """
    assert re.match(PERMISSION_VALIDATION,
                    data_key), "proposed metadata key is valid"

    user_md = get_user_metadata_by_key(session, user_id, data_key)

    if user_md:
        if data_value is None:
            user_md.delete(session)
            user_md = None
        else:
            user_md.data_value = data_value
            user_md.add(session)
    else:
        if data_value is None:
            # do nothing, a delete on a key that's not set
            return
        else:
            user_md = UserMetadata(user_id=user_id,
                                   data_key=data_key,
                                   data_value=data_value)
            user_md.add(session)

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

    return user_md
예제 #32
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()
예제 #33
0
def remove_tag_from_public_key(session, public_key, tag):
    # type: (Session, PublicKey, PublicKeyTag) -> None
    """Removes the tag from the given public key.

    Args:
        session(models.base.session.Session): database session
        public_key(models.public_key.PublicKey): the public key to be tagged
        tag(models.public_key_tag.PublicKeyTag): the tag to be removed from the public key

    Throws:
        TagNotOnKey if the tag was already assigned to the public key
    """
    mapping = (
        session.query(PublicKeyTagMap).filter_by(tag_id=tag.id, key_id=public_key.id).scalar()
    )

    if not mapping:
        raise TagNotOnKey()

    mapping.delete(session)
    Counter.incr(session, "updates")
    session.commit()
예제 #34
0
    def post(self, *args: Any, **kwargs: Any) -> None:
        name = self.get_path_argument("name")
        accountname = self.get_path_argument("accountname")
        mapping_id = int(self.get_path_argument("mapping_id"))

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

        if not 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)
        )
예제 #35
0
def edit_service_account(session, actor, service_account, description,
                         machine_set):
    # type: (Session, User, ServiceAccount, str, str) -> None
    """Update the description and machine set of a service account.

    Raises:
        PluginRejectedMachineSet: if some plugin rejected the machine set
    """
    if machine_set is not None:
        _check_machine_set(service_account, machine_set)

    service_account.description = description
    service_account.machine_set = machine_set
    Counter.incr(session, "updates")

    session.commit()

    AuditLog.log(session,
                 actor.id,
                 "edit_service_account",
                 "Edited service account.",
                 on_user_id=service_account.user.id)
예제 #36
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))
예제 #37
0
def test_permissions_aliased_permissions(
        mocker,
        session,
        standard_graph,
        http_client,
        base_url  # noqa: F811
):
    proxy = PluginProxy([PermissionAliasesPlugin()])
    mocker.patch("grouper.graph.get_plugin_proxy", return_value=proxy)

    # Force graph update
    Counter.incr(session, "updates")
    standard_graph.update_from_db(session)

    api_url = url(base_url, "/permissions/ssh")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    perms = [(group, p["argument"])
             for group, g in iteritems(body["data"]["groups"])
             for p in g["permissions"]]

    assert ("sad-team", "owner=sad-team") in perms
예제 #38
0
def grant_permission(session, group_id, permission_id, argument=""):
    """
    Grant a permission to this group. This will fail if the (permission, argument) has already
    been granted to this group.

    Args:
        session(models.base.session.Session): database session
        permission(Permission): a Permission object being granted
        argument(str): must match constants.ARGUMENT_VALIDATION

    Throws:
        AssertError if argument does not match ARGUMENT_VALIDATION regex
    """
    assert re.match(
        ARGUMENT_VALIDATION + r"$", argument
    ), "Permission argument does not match regex."

    mapping = PermissionMap(permission_id=permission_id, group_id=group_id, argument=argument)
    mapping.add(session)

    Counter.incr(session, "updates")

    session.commit()
예제 #39
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 = Permission.get(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()
예제 #40
0
def grant_permission_to_service_account(session, account, permission, argument=''):
    """
    Grant a permission to this service account. This will fail if the (permission, argument) has
    already been granted to this group.

    Args:
        session(models.base.session.Session): database session
        account(ServiceAccount): a ServiceAccount object being granted a permission
        permission(Permission): a Permission object being granted
        argument(str): must match constants.ARGUMENT_VALIDATION

    Throws:
        AssertError if argument does not match ARGUMENT_VALIDATION regex
    """
    assert re.match(ARGUMENT_VALIDATION, argument), 'Permission argument does not match regex.'

    mapping = ServiceAccountPermissionMap(
        permission_id=permission.id, service_account_id=account.id, argument=argument)
    mapping.add(session)

    Counter.incr(session, "updates")

    session.commit()
예제 #41
0
def disable_permission(session, permission_name, actor_user_id):
    """Set a permission as disabled.

    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 the permission
    """
    if permission_name in (entry[0] for entry in SYSTEM_PERMISSIONS):
        raise CannotDisableASystemPermission(permission_name)
    permission = get_permission(session, permission_name)
    if not permission:
        raise NoSuchPermission(name=permission_name)
    permission.enabled = False
    AuditLog.log(
        session,
        actor_user_id,
        "disable_permission",
        "Disabled permission.",
        on_permission_id=permission.id,
    )
    Counter.incr(session, "updates")
    session.commit()
예제 #42
0
def delete_public_key(session, user_id, key_id):
    """Delete a particular user's public key. This will remove all
        tags from the public key prior to deletion.

    Args:
        session(models.base.session.Session): database session
        user_id(int): id of user in question
        key_id(int): id of the user's key we want to delete

    Throws:
        KeyNotFound if specified key wasn't found
    """
    pkey = get_public_key(session, user_id, key_id)

    tag_mappings = session.query(PublicKeyTagMap).filter_by(key_id=key_id).all()
    for mapping in tag_mappings:
        remove_tag_from_public_key(session, pkey, mapping.tag)

    pkey.delete(session)

    Counter.incr(session, "updates")

    session.commit()
예제 #43
0
def grant_permission(
    session: Session, group_id: int, permission_id: int, argument: str = ""
) -> None:
    """Grant a permission to this group.

    This will fail if the (permission, argument) has already been granted to this group.

    Args:
        session: Database session
        group_id: ID of group to which to grant the permission
        permission_id: ID of permission to grant
        argument: Must match constants.ARGUMENT_VALIDATION

    Throws:
        AssertError if argument does not match ARGUMENT_VALIDATION regex
    """
    assert re.match(ARGUMENT_VALIDATION + r"$", argument), "Invalid permission argument"

    mapping = PermissionMap(permission_id=permission_id, group_id=group_id, argument=argument)
    mapping.add(session)

    Counter.incr(session, "updates")

    session.commit()
예제 #44
0
 def add(self, session):
     # type: (Session) -> ServiceAccount
     super().add(session)
     Counter.incr(session, "updates")
     return self
예제 #45
0
def persist_group_member_changes(
        session,  # type: Session
        group,  # type: Group
        requester,  # type: User
        member,  # type: Union[User, Group]
        status,  # type: str
        reason,  # type: str
        create_edge=False,  # type: bool
        **updates  # type: Any
):
    # type: (...) -> Request
    requested_at = datetime.utcnow()

    if "role" in updates:
        role = updates["role"]
        _validate_role(member.member_type, role)

    get_plugin_proxy().will_update_group_membership(session, group, member,
                                                    **updates)

    if create_edge:
        edge = _create_edge(session, group, member,
                            updates.get("role", "member"))
    else:
        edge = _get_edge(session, group, member)
        if not edge:
            raise MemberNotFound()

    changes = _serialize_changes(edge, **updates)

    request = Request(
        requester_id=requester.id,
        requesting_id=group.id,
        on_behalf_obj_type=member.member_type,
        on_behalf_obj_pk=member.id,
        requested_at=requested_at,
        edge_id=edge.id,
        status=status,
        changes=changes,
    ).add(session)
    session.flush()

    request_status_change = RequestStatusChange(
        request=request,
        user_id=requester.id,
        to_status=status,
        change_at=requested_at).add(session)
    session.flush()

    Comment(
        obj_type=OBJ_TYPES["RequestStatusChange"],
        obj_pk=request_status_change.id,
        user_id=requester.id,
        comment=reason,
        created_on=requested_at,
    ).add(session)
    session.flush()

    if status == "actioned":
        edge.apply_changes(request.changes)
        session.flush()

    Counter.incr(session, "updates")

    return request
예제 #46
0
파일: group.py 프로젝트: bsittler/merou
 def add(self, session):
     super().add(session)
     Counter.incr(session, "updates")
     return self
예제 #47
0
파일: group.py 프로젝트: bsittler/merou
 def disable(self):
     self.enabled = False
     Counter.incr(self.session, "updates")
예제 #48
0
파일: group.py 프로젝트: bsittler/merou
 def enable(self):
     self.enabled = True
     Counter.incr(self.session, "updates")
예제 #49
0
파일: user.py 프로젝트: graham/grouper
def disable_user(session, user):
    """Disables an enabled user"""
    user.enabled = False
    Counter.incr(session, "updates")
예제 #50
0
파일: user.py 프로젝트: yasaswyk/merou
 def add(self, session):
     # type: (Session) -> User
     super().add(session)
     Counter.incr(session, "updates")
     return self
예제 #51
0
    def add_member(self, requester, user_or_group, reason, status="pending",
                   expiration=None, role="member"):
        """ Add a member (User or Group) to this group.

            Arguments:
                requester: A User object of the person requesting the addition
                user_or_group: A User/Group object of the member
                reason: A comment on why this member should exist
                status: pending/actioned, whether the request needs approval
                        or should be immediate
                expiration: datetime object when membership should expire.
                role: member/manager/owner/np-owner of the Group.
        """
        now = datetime.utcnow()
        member_type = user_or_group.member_type

        if member_type == 1 and role != "member":
            raise InvalidRoleForMember("Groups can only have the role of 'member'")

        logging.debug(
            "Adding member (%s) to %s", user_or_group.name, self.groupname
        )

        edge, new = GroupEdge.get_or_create(
            self.session,
            group_id=self.id,
            member_type=member_type,
            member_pk=user_or_group.id,
        )

        # TODO(herb): this means all requests by this user to this group will
        # have the same role. we should probably record the role specifically
        # on the request and use that as the source on the UI
        edge._role = GROUP_EDGE_ROLES.index(role)

        self.session.flush()

        request = Request(
            requester_id=requester.id,
            requesting_id=self.id,
            on_behalf_obj_type=member_type,
            on_behalf_obj_pk=user_or_group.id,
            requested_at=now,
            edge_id=edge.id,
            status=status,
            changes=build_changes(
                edge, role=role, expiration=expiration, active=True
            )
        ).add(self.session)
        self.session.flush()

        request_status_change = RequestStatusChange(
            request=request,
            user_id=requester.id,
            to_status=status,
            change_at=now
        ).add(self.session)
        self.session.flush()

        Comment(
            obj_type=3,
            obj_pk=request_status_change.id,
            user_id=requester.id,
            comment=reason,
            created_on=now
        ).add(self.session)

        if status == "actioned":
            edge.apply_changes(request)
            self.session.flush()

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

        return request.id
예제 #52
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.
        """
        now = datetime.utcnow()
        member_type = user_or_group.member_type

        if member_type == 1 and "role" in kwargs and kwargs["role"] != "member":
            raise InvalidRoleForMember("Groups can only have the role of 'member'")

        logging.debug(
            "Editing member (%s) in %s", user_or_group.name, self.groupname
        )

        edge = GroupEdge.get(
            self.session,
            group_id=self.id,
            member_type=member_type,
            member_pk=user_or_group.id,
        )
        self.session.flush()

        if not edge:
            raise MemberNotFound()

        request = Request(
            requester_id=requester.id,
            requesting_id=self.id,
            on_behalf_obj_type=member_type,
            on_behalf_obj_pk=user_or_group.id,
            requested_at=now,
            edge_id=edge.id,
            status="actioned",
            changes=build_changes(
                edge, **kwargs
            ),
        ).add(self.session)
        self.session.flush()

        request_status_change = RequestStatusChange(
            request=request,
            user_id=requester.id,
            to_status="actioned",
            change_at=now,
        ).add(self.session)
        self.session.flush()

        Comment(
            obj_type=OBJ_TYPES_IDX.index("RequestStatusChange"),
            obj_pk=request_status_change.id,
            user_id=requester.id,
            comment=reason,
            created_on=now,
        ).add(self.session)

        edge.apply_changes(request)
        self.session.flush()

        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)

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