예제 #1
0
def test_serializer_loads_bad_data():
    class BirdSchema(BaseSchema):
        flying = fields.Boolean(required=True)

    serializer = MsgpackSerializer(BirdSchema)
    for raw in (packb(0), packb([]), packb({}), b"dummy"):
        with pytest.raises(SerdeError):
            serializer.loads(raw)
예제 #2
0
파일: base.py 프로젝트: Scille/parsec-cloud
def any_cmd_req_factory(name: str, *req_types: Type[BaseReq]):  # type: ignore[no-untyped-def]
    assert name.endswith("Req")

    class AnyCmdReqSchema(OneOfSchemaLegacy):
        type_field = "cmd"
        type_schemas = {
            x.SCHEMA_CLS._declared_fields["cmd"].default: x.SCHEMA_CLS for x in req_types
        }

        def get_obj_type(self, obj: Dict[str, object]) -> Optional[str]:
            return cast(str, obj.get("cmd"))

    AnyCmdReqSchema.__name__ = f"{name}Schema"

    serializer = MsgpackSerializer(AnyCmdReqSchema, InvalidMessageError, MessageSerializationError)

    @classmethod  # type: ignore[misc]
    def load(cls, raw: bytes) -> Dict[Any, Any]:  # type: ignore[no-untyped-def, misc]
        return serializer.loads(raw)

    fields = {"load": load, "TYPES": req_types}
    suffix = "Req"
    for rep_type in req_types:
        assert rep_type.__name__.endswith(suffix)
        rep_type_name = rep_type.__name__[: -len(suffix)]
        assert rep_type_name not in fields
        fields[rep_type_name] = rep_type

    return type(name, (), fields)
예제 #3
0
파일: base.py 프로젝트: Scille/parsec-cloud
def cmd_rep_factory(  # type: ignore[no-untyped-def]
    name: str, *rep_types: Type[BaseRep]
):
    assert name.endswith("Rep")

    class RepSchema(OneOfSchemaLegacy):
        type_field = "status"
        type_schemas = {
            x.SCHEMA_CLS._declared_fields["status"].default: x.SCHEMA_CLS for x in rep_types
        }

        def get_obj_type(self, obj: Dict[str, object]) -> str:
            return cast(str, obj.get("status"))

    RepSchema.__name__ = f"{name}Schema"

    serializer = MsgpackSerializer(RepSchema, InvalidMessageError, MessageSerializationError)

    @classmethod  # type: ignore[misc]
    def load(cls, raw: bytes) -> Dict[Any, Any]:  # type: ignore[no-untyped-def, misc]
        return serializer.loads(raw)

    fields = {"load": load, "TYPES": rep_types}
    for rep_type in rep_types:
        assert rep_type.__name__.startswith(name)
        rep_type_name = rep_type.__name__[len(name) :]
        assert rep_type_name not in fields
        fields[rep_type_name] = rep_type

    return type(name, (), fields)
예제 #4
0
파일: base.py 프로젝트: Scille/parsec-cloud
    def __new__(  # type: ignore[no-untyped-def, misc]
        cls, name: str, bases: Tuple[type, ...], nmspc: Dict[str, Any]
    ):
        # Sanity checks
        if "SCHEMA_CLS" not in nmspc:
            raise RuntimeError("Missing attribute `SCHEMA_CLS` in class definition")
        if not issubclass(nmspc["SCHEMA_CLS"], cls.BASE_SCHEMA_CLS):
            raise RuntimeError(f"Attribute `SCHEMA_CLS` must inherit {cls.BASE_SCHEMA_CLS!r}")

        # Special case if we are defining `BaseReq/BaseRep`
        if nmspc["SCHEMA_CLS"] is not cls.BASE_SCHEMA_CLS:
            # Sanity check: discriminant field should be defined as check constant
            discriminant_field = nmspc["SCHEMA_CLS"]._declared_fields.get(cls.DISCRIMINANT_FIELD)
            if not discriminant_field or not isinstance(discriminant_field, fields.CheckedConstant):
                raise RuntimeError(
                    f"Attribute `SCHEMA_CLS` must contain a `{cls.DISCRIMINANT_FIELD}` field"
                )

        raw_cls = type.__new__(cls, name, bases, nmspc)

        # Sanity checks: class SCHEMA_CLS needs to define parents SCHEMA_CLS fields
        schema_cls_fields = set(nmspc["SCHEMA_CLS"]._declared_fields)
        bases_schema_cls = (base for base in bases if hasattr(base, "SCHEMA_CLS"))
        for base in bases_schema_cls:
            assert (
                base.SCHEMA_CLS._declared_fields.keys()  # type: ignore[attr-defined]
                <= schema_cls_fields
            )

        # Sanity check: attr fields need to be defined in SCHEMA_CLS
        if "__attrs_attrs__" in nmspc:
            assert {att.name for att in nmspc["__attrs_attrs__"]} <= schema_cls_fields

        raw_cls.SERIALIZER = MsgpackSerializer(  # type: ignore[attr-defined]
            nmspc["SCHEMA_CLS"], InvalidMessageError, MessageSerializationError
        )

        # Define attribute `BaseTypedReqSchema.TYPE`
        raw_cls.SCHEMA_CLS.TYPE = raw_cls  # type: ignore[attr-defined]

        return raw_cls
예제 #5
0
    type_field_remove = False
    type_schemas = {
        "foreground": ForegroundReqSchema,
        "new_instance": NewInstanceReqSchema
    }

    def get_obj_type(self, obj):
        return obj["cmd"]


class CommandRepSchema(BaseSchema):
    status = fields.String(required=True)
    reason = fields.String(allow_none=True)


cmd_req_serializer = MsgpackSerializer(CommandReqSchema)
cmd_rep_serializer = MsgpackSerializer(CommandRepSchema)

DEFAULT_WIN32_MUTEX_NAME = "parsec-cloud"


@contextmanager
def _install_win32_mutex(mutex_name: str):

    from parsec.win32 import CreateMutex, CloseHandle, GetLastError, ERROR_ALREADY_EXISTS

    try:
        mutex = CreateMutex(None, False, mutex_name)
    except WindowsError as exc:
        raise IPCServerError(
            f"Cannot create mutex `{mutex_name}`: {exc}") from exc
예제 #6
0
class DeviceFileSchema(OneOfSchema):
    type_field = "type"
    type_schemas = {
        DeviceFileType.PASSWORD: PasswordDeviceFileSchema(),
        DeviceFileType.RECOVERY: RecoveryDeviceFileSchema(),
        DeviceFileType.SMARTCARD: SmartcardDeviceFileSchema(),
    }

    def get_obj_type(self, obj: Dict[str, object]) -> object:
        return obj["type"]


legacy_key_file_serializer = MsgpackSerializer(
    LegacyDeviceFileSchema,
    validation_exc=LocalDeviceValidationError,
    packing_exc=LocalDevicePackingError,
)

key_file_serializer = MsgpackSerializer(
    DeviceFileSchema,
    validation_exc=LocalDeviceValidationError,
    packing_exc=LocalDevicePackingError)


def generate_new_device(
    organization_addr: BackendOrganizationAddr,
    device_id: Optional[DeviceID] = None,
    profile: UserProfile = UserProfile.STANDARD,
    human_handle: Optional[HumanHandle] = None,
    device_label: Optional[DeviceLabel] = None,
예제 #7
0
    __id__ = fields.String(required=True)
    __signal__ = fields.EnumCheckedConstant(
        BackendEvent.PKI_ENROLLMENTS_UPDATED, required=True)
    organization_id = OrganizationIDField(required=True)


class BackendEventSchema(OneOfSchema):
    type_field = "__signal__"
    type_schemas = {
        BackendEvent.DEVICE_CREATED: DeviceCreatedSchema,
        BackendEvent.INVITE_CONDUIT_UPDATED: InviteConduitUpdatedSchema,
        BackendEvent.USER_CREATED: UserCreatedSchema,
        BackendEvent.USER_REVOKED: UserRevokedSchema,
        BackendEvent.ORGANIZATION_EXPIRED: OrganizationExpiredSchema,
        BackendEvent.PINGED: PingedSchema,
        BackendEvent.MESSAGE_RECEIVED: MessageReceivedSchema,
        BackendEvent.INVITE_STATUS_CHANGED: InviteStatusChangedSchema,
        BackendEvent.REALM_MAINTENANCE_FINISHED:
        RealmMaintenanceFinishedSchema,
        BackendEvent.REALM_MAINTENANCE_STARTED: RealmMaintenanceStartedSchema,
        BackendEvent.REALM_VLOBS_UPDATED: RealmVlobsUpdatedSchema,
        BackendEvent.REALM_ROLES_UPDATED: RealmRolesUpdatedSchema,
        BackendEvent.PKI_ENROLLMENTS_UPDATED: PkiEnrollmentUpdatedSchema,
    }

    def get_obj_type(self, obj):
        return obj["__signal__"]


backend_event_serializer = MsgpackSerializer(BackendEventSchema)
예제 #8
0
파일: base.py 프로젝트: Scille/parsec-cloud
def serializer_factory(schema_cls: Type[BaseSchema]) -> MsgpackSerializer:
    return MsgpackSerializer(schema_cls, InvalidMessageError, MessageSerializationError)
예제 #9
0
def test_repr_serializer():
    class MySchema(BaseSchema):
        pass

    serializer = MsgpackSerializer(MySchema)
    assert repr(serializer) == "MsgpackSerializer(schema=MySchema)"
예제 #10
0
def serializer_factory(schema_cls):
    return MsgpackSerializer(schema_cls, InvalidMessageError,
                             MessageSerializationError)
예제 #11
0
        raise NotImplementedError()

    @staticmethod
    def can_decrypt(ciphertext: bytes) -> bool:
        raise NotImplementedError()


class PasswordPayloadSchema(BaseSchema):
    type = fields.CheckedConstant("password", required=True)
    salt = fields.Bytes(required=True)
    ciphertext = fields.Bytes(required=True)


password_payload_serializer = MsgpackSerializer(
    PasswordPayloadSchema,
    validation_exc=LocalDeviceValidationError,
    packing_exc=LocalDevicePackingError,
)


class PasswordDeviceEncryptor(BaseLocalDeviceEncryptor):
    def __init__(self, password):
        self.password = password

    def encrypt(self, plaintext: bytes) -> bytes:
        """
        Raises:
            LocalDeviceCryptoError
            LocalDeviceValidationError
            LocalDevicePackingError
        """