Example #1
0
class DeviceFileSchema(LegacyDeviceFileSchema):
    """Schema for device files that does not rely on the filename for complementary information."""

    # Override those fields to make them required (although `None` is still valid)
    human_handle = HumanHandleField(required=True, allow_none=True)
    device_label = fields.String(required=True, allow_none=True)

    # Store device ID, organization ID and slug in the device file
    # For legacy versions, this information is available in the file name
    device_id = DeviceIDField(required=True)
    organization_id = OrganizationIDField(required=True)
    slug = fields.String(required=True)
Example #2
0
    class SCHEMA_CLS(BaseSchema):
        organization_addr = BackendOrganizationAddrField(required=True)
        device_id = DeviceIDField(required=True)
        device_label = fields.String(allow_none=True, missing=None)
        human_handle = HumanHandleField(allow_none=True, missing=None)
        signing_key = fields.SigningKey(required=True)
        private_key = fields.PrivateKey(required=True)
        # `profile` replaces `is_admin` field (which is still required for backward
        # compatibility), hence `None` is not allowed
        is_admin = fields.Boolean(required=True)
        profile = UserProfileField(allow_none=False)
        user_manifest_id = EntryIDField(required=True)
        user_manifest_key = fields.SecretKey(required=True)
        local_symkey = fields.SecretKey(required=True)

        @post_load
        def make_obj(self, data):
            # Handle legacy `is_admin` field
            default_profile = UserProfile.ADMIN if data.pop(
                "is_admin") else UserProfile.STANDARD
            try:
                profile = data["profile"]
            except KeyError:
                data["profile"] = default_profile
            else:
                if default_profile == UserProfile.ADMIN and profile != UserProfile.ADMIN:
                    raise ValidationError(
                        "Fields `profile` and `is_admin` have incompatible values"
                    )

            return LocalDevice(**data)
Example #3
0
class HumanFindReqSchema(BaseReqSchema):
    query = fields.String(required=True, allow_none=True)
    omit_revoked = fields.Boolean(required=True)
    omit_non_human = fields.Boolean(required=True)
    # First page is 1
    page = fields.Int(required=True, validate=lambda n: n > 0)
    per_page = fields.Integer(required=True, validate=lambda n: 0 < n <= 100)
Example #4
0
class OrganizationBootstrapReqSchema(BaseReqSchema):
    bootstrap_token = fields.String(required=True)
    root_verify_key = fields.VerifyKey(required=True)
    user_certificate = fields.Bytes(required=True)
    device_certificate = fields.Bytes(required=True)
    redacted_user_certificate = fields.Bytes(required=True)
    redacted_device_certificate = fields.Bytes(required=True)
class UserClaimSchema(UnknownCheckedSchema):
    type = fields.CheckedConstant("user_claim", required=True)
    token = fields.String(required=True)
    # Note claiming user also imply creating a first device
    device_id = fields.DeviceID(required=True)
    public_key = fields.PublicKey(required=True)
    verify_key = fields.VerifyKey(required=True)
Example #6
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("ping", required=True)
        ping = fields.String(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return PingMessageContent(**data)
Example #7
0
class MessageReceivedSchema(BaseSchema):
    __id__ = fields.String(required=True)
    __signal__ = fields.EnumCheckedConstant(BackendEvent.MESSAGE_RECEIVED,
                                            required=True)
    organization_id = OrganizationIDField(required=True)
    author = DeviceIDField(required=True)
    recipient = UserIDField(required=True)
    index = fields.Integer(required=True)
Example #8
0
class RealmMaintenanceStartedSchema(BaseSchema):
    __id__ = fields.String(required=True)
    __signal__ = fields.EnumCheckedConstant(
        BackendEvent.REALM_MAINTENANCE_STARTED, required=True)
    organization_id = OrganizationIDField(required=True)
    author = DeviceIDField(required=True)
    realm_id = RealmIDField(required=True)
    encryption_revision = fields.Integer(required=True)
Example #9
0
class DeviceCreatedSchema(BaseSchema):
    __id__ = fields.String(required=True)
    __signal__ = fields.EnumCheckedConstant(BackendEvent.DEVICE_CREATED,
                                            required=True)
    organization_id = OrganizationIDField(required=True)
    device_id = DeviceIDField(required=True)
    device_certificate = fields.Bytes(required=True)
    encrypted_answer = fields.Bytes(required=True)
Example #10
0
class InviteStatusChangedSchema(BaseSchema):
    __id__ = fields.String(required=True)
    __signal__ = fields.EnumCheckedConstant(BackendEvent.INVITE_STATUS_CHANGED,
                                            required=True)
    organization_id = OrganizationIDField(required=True)
    greeter = UserIDField(required=True)
    token = InvitationTokenField(required=True)
    status = InvitationStatusField(required=True)
Example #11
0
class UserCreatedSchema(BaseSchema):
    __id__ = fields.String(required=True)
    __signal__ = fields.EnumCheckedConstant(BackendEvent.USER_CREATED,
                                            required=True)
    organization_id = OrganizationIDField(required=True)
    user_id = UserIDField(required=True)
    user_certificate = fields.Bytes(required=True)
    first_device_id = DeviceIDField(required=True)
    first_device_certificate = fields.Bytes(required=True)
Example #12
0
class RealmRolesUpdatedSchema(BaseSchema):
    __id__ = fields.String(required=True)
    __signal__ = fields.EnumCheckedConstant(BackendEvent.REALM_ROLES_UPDATED,
                                            required=True)
    organization_id = OrganizationIDField(required=True)
    author = DeviceIDField(required=True)
    realm_id = RealmIDField(required=True)
    user = UserIDField(required=True)
    role = RealmRoleField(required=True, allow_none=True)
Example #13
0
class RealmVlobsUpdatedSchema(BaseSchema):
    __id__ = fields.String(required=True)
    __signal__ = fields.EnumCheckedConstant(BackendEvent.REALM_VLOBS_UPDATED,
                                            required=True)
    organization_id = OrganizationIDField(required=True)
    author = DeviceIDField(required=True)
    realm_id = RealmIDField(required=True)
    checkpoint = fields.Integer(required=True)
    src_id = VlobIDField(required=True)
    src_version = fields.Integer(required=True)
Example #14
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("invite_device_data", required=True)
        # Claimer ask for device_label, but greeter has final word on this
        requested_device_label = fields.String(allow_none=True, missing=None)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return InviteDeviceData(**data)
Example #15
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("device_claim", required=True)
        token = fields.String(required=True)
        device_id = DeviceIDField(required=True)
        verify_key = fields.VerifyKey(required=True)
        answer_public_key = fields.PublicKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return DeviceClaimContent(**data)
Example #16
0
class UserSchema(UnknownCheckedSchema):
    user_id = fields.String(required=True)
    is_admin = fields.Boolean(required=True)
    created_on = fields.DateTime(required=True)

    certified_user = fields.Bytes(required=True)
    user_certifier = fields.DeviceID(allow_none=True)

    devices = fields.Map(fields.DeviceName(),
                         fields.Nested(DeviceSchema),
                         required=True)
Example #17
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.CheckedConstant("device_certificate", required=True)
        device_id = DeviceIDField(required=True)
        verify_key = fields.VerifyKey(required=True)
        # Device label can be none in case of redacted certificate
        device_label = fields.String(allow_none=True, missing=None)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return DeviceCertificateContent(**data)
Example #18
0
class DeviceFileSchema(BaseSchema):
    type = fields.CheckedConstant("password", required=True)
    salt = fields.Bytes(required=True)
    ciphertext = fields.Bytes(required=True)

    # Since human_handle/device_label has been introduced, device_id is
    # redacted (i.e. user_id and device_name are 2 random uuids), hence
    # those fields have been added to the device file so the login page in
    # the GUI can use them to provide useful information.
    human_handle = HumanHandleField(allow_none=True, missing=None)
    device_label = fields.String(allow_none=True, missing=None)
Example #19
0
class BaseReqSchema(UnknownCheckedSchema):
    cmd = fields.String(required=True)

    @post_load
    def _drop_cmd_field(self, item):
        if self.drop_cmd_field:
            item.pop("cmd")
        return item

    def __init__(self, drop_cmd_field=True, **kwargs):
        super().__init__(**kwargs)
        self.drop_cmd_field = drop_cmd_field
Example #20
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("user_claim", required=True)
        token = fields.String(required=True)
        # Note claiming user also imply creating a first device
        device_id = DeviceIDField(required=True)
        public_key = fields.PublicKey(required=True)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data: Dict[str, Any]) -> "APIV1_UserClaimContent":  # type: ignore[misc]
            data.pop("type")
            return APIV1_UserClaimContent(**data)
Example #21
0
class BaseReqSchema(BaseSchema):
    cmd = fields.String(required=True)

    @post_load
    def _drop_cmd_field(self, item: Dict[str, T]) -> Dict[str, T]:  # type: ignore[misc]
        if self.drop_cmd_field:
            item.pop("cmd")
        return item

    def __init__(self, drop_cmd_field: bool = True, **kwargs: object):
        super().__init__(**kwargs)
        self.drop_cmd_field = drop_cmd_field
Example #22
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        type = fields.EnumCheckedConstant(MessageContentType.PING,
                                          required=True)
        ping = fields.String(required=True)

        @post_load
        def make_obj(
            self,
            data: Dict[str,
                       Any]) -> "PingMessageContent":  # type: ignore[misc]
            data.pop("type")
            return PingMessageContent(**data)
Example #23
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("invite_user_confirmation", required=True)
        device_id = DeviceIDField(required=True)
        device_label = fields.String(allow_none=True, missing=None)
        human_handle = HumanHandleField(allow_none=True, missing=None)
        profile = UserProfileField(required=True)
        root_verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return InviteUserConfirmation(**data)
Example #24
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("x509_certificate", required=True)
        issuer = fields.Dict(required=True)
        subject = fields.Dict(required=True)
        der_x509_certificate = fields.Bytes(required=True)
        certificate_sha1 = fields.Bytes(required=True)
        certificate_id = fields.String(required=True, allow_none=True)

        @post_load
        def make_obj(self, data):
            data.pop("type", None)
            return X509Certificate(**data)
Example #25
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("device_claim", required=True)
        token = fields.String(required=True)
        device_id = DeviceIDField(required=True)
        verify_key = fields.VerifyKey(required=True)
        answer_public_key = fields.PublicKey(required=True)

        @post_load
        def make_obj(  # type: ignore[misc]
            self, data: Dict[str, Any]
        ) -> "APIV1_DeviceClaimContent":
            data.pop("type")
            return APIV1_DeviceClaimContent(**data)
Example #26
0
    class SCHEMA_CLS(BaseSchema):
        type = fields.CheckedConstant("invite_user_data", required=True)
        # Claimer ask for device_label/human_handle, but greeter has final word on this
        requested_device_label = fields.String(allow_none=True, missing=None)
        requested_human_handle = HumanHandleField(allow_none=True, missing=None)
        # Note claiming user also imply creating a first device
        public_key = fields.PublicKey(required=True)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data):
            data.pop("type")
            return InviteUserData(**data)
Example #27
0
class ApiReleaseSchema(BaseSchema):
    draft = fields.Boolean(missing=False)
    prerelease = fields.Boolean(missing=False)
    tag_name = fields.String(required=True)
    assets = fields.List(fields.Nested(ApiReleaseAssetSchema), missing=[])

    @post_load
    def add_version_field(self, data):
        try:
            data["version"] = Version(data["tag_name"])
        except ValueError:
            data["version"] = None
        return data
Example #28
0
    class SCHEMA_CLS(BaseSignedDataSchema):
        # Override author field to allow for None value if signed by the root key
        author = DeviceIDField(required=True, allow_none=True)

        type = fields.CheckedConstant("device_certificate", required=True)
        device_id = DeviceIDField(required=True)
        # Device label can be none in case of redacted certificate
        device_label = fields.String(allow_none=True, missing=None)
        verify_key = fields.VerifyKey(required=True)

        @post_load
        def make_obj(self, data: Dict[str, Any]) -> "DeviceCertificateContent":
            data.pop("type")
            return DeviceCertificateContent(**data)
Example #29
0
class PkiEnrollmentSubmitReqSchema(BaseReqSchema):
    enrollment_id = fields.UUID(required=True)
    # Existing enrollment with SUMBITTED status prevent submitting new
    # enrollment with similir x509 certificate unless force flag is set.
    force = fields.Boolean(required=True)

    submitter_der_x509_certificate = fields.Bytes(required=True)
    # Duplicated certificate email field. (The backend need to check if the email is used without loading the certificate)
    submitter_der_x509_certificate_email = fields.String(required=False,
                                                         missing=None,
                                                         allow_none=True)
    submit_payload_signature = fields.Bytes(required=True)
    submit_payload = fields.Bytes(
        required=True)  # Signature should be checked before loading
Example #30
0
class APIV1_OrganizationBootstrapReqSchema(BaseReqSchema):
    bootstrap_token = fields.String(required=True)
    root_verify_key = fields.VerifyKey(required=True)
    user_certificate = fields.Bytes(required=True)
    device_certificate = fields.Bytes(required=True)
    # Same certificates than above, but expurged of human_handle/device_label
    # Backward compatibility prevent those field to be required, however
    # they should be considered so by recent version of Parsec (hence the
    # `allow_none=False`).
    # Hence only old version of Parsec will provide a payload with missing
    # redacted fields. In such case we consider the non-redacted can also
    # be used as redacted given the to-be-redacted fields have been introduce
    # in later version of Parsec.
    redacted_user_certificate = fields.Bytes(allow_none=False)
    redacted_device_certificate = fields.Bytes(allow_none=False)