Beispiel #1
0
class CreateGroupMembership(JSONAPIData):
    """The data to add a user to a group."""

    validator = Schema.get_validator(
        "bulk_api/command/create_group_membership.json")

    @classmethod
    def create(cls, user_ref, group_ref):
        """
        Create a create group membership body for adding users to groups.

        :param user_ref: Custom user reference
        :param group_ref: Custom group reference
        :return:
        """
        return super().create(
            DataType.GROUP_MEMBERSHIP,
            relationships={
                "member": {
                    "data": {
                        "type": DataType.USER.value,
                        "id": {
                            "$ref": user_ref
                        }
                    }
                },
                "group": {
                    "data": {
                        "type": DataType.GROUP.value,
                        "id": {
                            "$ref": group_ref
                        }
                    }
                },
            },
        )

    @property
    def member(self):
        """The user which is a member of this group.

        :return: A value object with `id` and `ref` properties.
        """
        return _IdRef(self.relationships["member"]["data"]["id"])

    @property
    def group(self):
        """The group which this user is a member of.

        :return: A value object with `id` and `ref` properties.
        """
        return _IdRef(self.relationships["group"]["data"]["id"])
Beispiel #2
0
class UpsertUser(JSONAPIData):
    """The data to upsert a user."""

    validator = Schema.get_validator("bulk_api/command/upsert_user.json")

    @classmethod
    def create(cls, _id, attributes):
        """
        Create an upsert user body.

        :param _id: User id
        :param attributes: User attributes
        :return:
        """
        return super().create(DataType.USER, _id=_id, attributes=attributes)
Beispiel #3
0
class Command(Model):
    """A single abstract command provided to the API."""

    validator = Schema.get_validator("bulk_api/wrapper.json")
    validation_error_title = "Cannot interpret command as the wrapper is malformed"

    def validate(self):
        super().validate()

        if isinstance(self.body, Model):
            self.body.validate()

    @classmethod
    def create(cls, type_, body):
        """
        Create a command.

        :param type_: The CommandType of the command
        :param body: The payload for the command
        :return: An instance of Command
        """
        return cls([CommandType(type_).value, cls.extract_raw(body)])

    @property
    def type(self):
        """
        Get the command type.

        :return: The CommandType of this command
        """
        return CommandType(self.raw[0])

    @property
    def body(self):
        """
        Get the body of this command.

        :return: The raw body
        """
        return self.raw[1]

    def __repr__(self):
        return f"<{self.__class__.__name__} {self.body}>"
Beispiel #4
0
class Configuration(Model):
    validator = Schema.get_validator("bulk_api/command/configuration.json")

    WILD_CARD = "*"

    @classmethod
    def create(cls, effective_user, total_instructions):
        """
        Create a configuration object.

        :param effective_user: User to execute the command as
        :param total_instructions: Number of instructions (including this)
        """
        return cls({
            "view":
            None,
            "user": {
                "effective": effective_user
            },
            "instructions": {
                "total": int(total_instructions)
            },
            "defaults": [
                ["create", "*", {
                    "on_duplicate": "continue"
                }],
                ["upsert", "*", {
                    "merge_query": True
                }],
            ],
        })

    @property
    def view(self):
        """The return type of view requested by the user."""
        return self.raw["view"]

    @property
    def effective_user(self):
        """The user to execute the request as."""
        return self.raw["user"]["effective"]

    @property
    def total_instructions(self):
        """
        The number of instructions in the request.

        This count includes configuration commands.
        """
        return self.raw["instructions"]["total"]

    def defaults_for(self, command_type, data_type):
        """
        Provide default configuration for the given command and data type.

        This will use any wild card options first, overlaying more specific
        defaults as they are found.

        :param command_type: Type of modification (e.g. Types.UPSERT)
        :param data_type: Data type being modified
        :return: A dict of config
        """
        defaults = self._command_defaults

        config = {}

        wild = defaults.get(self.WILD_CARD, {})
        specific = defaults.get(CommandType(command_type), {})
        data_type = DataType(data_type)

        for container in (wild, specific):
            if self.WILD_CARD in container:
                config.update(container[self.WILD_CARD])

            if data_type in container:
                config.update(container[data_type])

        return config

    @property
    @lru_cache(1)
    def _command_defaults(self):
        config = defaultdict(dict)

        for command_type, data_type, defaults in self.raw["defaults"]:
            if command_type != self.WILD_CARD:
                command_type = CommandType(command_type)

            if data_type != self.WILD_CARD:
                data_type = DataType(data_type)

            config[command_type][data_type] = defaults

        return config
Beispiel #5
0
class CreateGroupMembership(JSONAPIData):
    """The data to add a user to a group."""

    validator = Schema.get_validator(
        "bulk_api/command/create_group_membership.json")

    @classmethod
    def create(cls, user_id, group_ref):
        """
        Create a create group membership body for adding users to groups.

        :param user_id: User id
        :param group_ref: Custom group reference
        :return:
        """
        return super().create(
            DataType.GROUP_MEMBERSHIP,
            relationships={
                "member": {
                    "data": {
                        "type": DataType.USER.value,
                        "id": user_id
                    }
                },
                "group": {
                    "data": {
                        "type": DataType.GROUP.value,
                        "id": {
                            "$ref": group_ref
                        }
                    }
                },
            },
        )

    @property
    def member_id(self):
        """The user which is a member of this group."""

        return self.relationships["member"]["data"]["id"]

    @property
    def group_id(self):
        """The group the user is a member of."""

        _group_id = self._group_id
        if "$ref" in _group_id:
            return None

        return _group_id

    @property
    def group_ref(self):
        """
        A client provided reference for this group.

        If you don't know the group id yet, you can use your own reference.
        """
        return self._group_id.get("$ref")

    @property
    def _group_id(self):
        return self.relationships["group"]["data"]["id"]
Beispiel #6
0
class UpsertGroup(UpsertBody):
    """The data to upsert a group."""

    validator = Schema.get_validator("bulk_api/command/upsert_group.json")
    data_type = DataType.GROUP
    query_fields = ["authority", "authority_provided_id"]
Beispiel #7
0
class UpsertUser(UpsertBody):
    """The data to upsert a user."""

    validator = Schema.get_validator("bulk_api/command/upsert_user.json")
    data_type = DataType.USER
    query_fields = ["authority", "username"]