Esempio n. 1
0
    def test_limits(self):
        try:
            ProtocolBase().from_string(Integer, "1" * (Integer.__max_str_len__ + 1))
        except:
            pass
        else:
            raise Exception("must fail.")

        ProtocolBase().from_string(UnsignedInteger, "-1") # This is not supposed to fail.

        try:
            UnsignedInteger.validate_native(-1)  # This is supposed to fail.
        except:
            pass
        else:
            raise Exception("must fail.")
Esempio n. 2
0
class HelloWorldService(ServiceBase):
    @rpc(Unicode(default='World'), UnsignedInteger(default=5),
                                                    _returns=Iterable(Unicode))
    def say_hello(ctx, name, times):
        # workaround for Python2's lacking of nonlocal
        times = [times]

        def _cb(push):
            # This callback is called immediately after the function returns.

            if times[0] > 0:
                times[0] -= 1

                data = u'Hello, %s' % name
                print data

                # The object passed to the append() method is immediately
                # serialized to bytes and pushed to the response stream's
                # file-like object.
                push.append(data)

                # When a push-callback returns anything other than a deferred,
                # the response gets closed.
                return deferLater(reactor, 1, _cb, push)

        # This is Spyne's way of returning NOT_DONE_YET
        return Iterable.Push(_cb)

    @rpc(Unicode(default='World'), _returns=Iterable(Unicode))
    def say_hello_forever(ctx, name):
        def _cb(push):
            push.append(u'Hello, %s' % name)
            return deferLater(reactor, 0.1, _cb, push)

        return Iterable.Push(_cb)
Esempio n. 3
0
    def test_limits(self):
        try:
            ProtocolBase().from_string(Integer,
                                       "1" * (Integer.__max_str_len__ + 1))
        except:
            pass
        else:
            raise Exception("must fail.")

        ProtocolBase().from_string(UnsignedInteger,
                                   "-1")  # This is not supposed to fail.

        try:
            UnsignedInteger.validate_native(-1)  # This is supposed to fail.
        except:
            pass
        else:
            raise Exception("must fail.")
Esempio n. 4
0
class Email(ComplexModel):
    _type_info = [
        #
        # Metadata
        #
        ('id',
         JmapId(
             sub_name='id',
             doc="Id (immutable; server-set) The id of the Email object. Note "
             "that this is the JMAP object id, NOT the Message-ID header "
             "field value of the message [@!RFC5322].")),
        ('blob_id',
         JmapId(sub_name='blobId',
                doc="Id (immutable; server-set) The id representing the raw "
                "octets of the message [@!RFC5322] for this Email. This may "
                "be used to download the raw original message or to attach it "
                "directly to another Email, etc.")),
        ('thread_id',
         JmapId(sub_name='threadId',
                doc="(immutable; server-set) The id of the Thread to which "
                "this Email belongs.")),
        (
            'mailbox_ids',
            AnyDict(  # this is supposed to be a JmapId: Boolean dict
                sub_name='mailboxIds',
                doc="The set of Mailbox ids this Email belongs to. An "
                "Email in the mail store MUST belong to one or more Mailboxes "
                "at all times (until it is destroyed). The set is represented "
                "as an object, with each key being a Mailbox id. The value "
                "for each key in the object MUST be true.")),
        (
            'keywords',
            AnyDict(  # this is supposed to be a String: Boolean dict
                sub_name='keywords',
                doc="(default: {}) A set of keywords that apply "
                "to the Email. The set is represented as an object, with the "
                "keys being the keywords. The value for each key in the "
                "object MUST be true.")),
        ('size',
         UnsignedInteger(
             sub_name='size',
             doc="(immutable; server-set) The size, in octets, "
             "of the raw data for the message [@!RFC5322] (as referenced "
             "by the blobId, i.e., the number of octets in the file the "
             "user would download).")),
        ('received_at',
         UtcDate(sub_name='receivedAt',
                 doc="(immutable; default: time of creation on server) The "
                 "date the Email was received by the message store. This is "
                 "the internal date in IMAP [@?RFC3501].")),
    ]
Esempio n. 5
0
class DaemonConfig(ComplexModel):
    SECTION_NAME = 'basic'

    daemonize = Boolean(default=False)
    """Fork the process to the background."""

    log_file = AbsolutePath
    """Log file."""

    pid_file = AbsolutePath
    """File that will contain the pid of the daemon process."""

    config_file = AbsolutePath
    """Alternative configuration file.."""

    uid = SystemUser
    """Daemon will drop privileges and switch to this uid when specified"""

    gid = SystemGroup
    """Daemon will drop privileges and switch to this gid when specified"""

    log_level = Unicode(values=['DEBUG', 'INFO'], default='DEBUG')
    """Logging level"""

    show_rpc = Boolean(default=False)
    """Log raw request and response data."""

    secret = ByteArray(default_factory=lambda: [os.urandom(64)],
                       no_cmdline=True)
    """Cookie encryption key. Keep secret."""

    thread_min = UnsignedInteger(default=3)
    """Min number of threads in the thread pool"""

    thread_max = UnsignedInteger(default=10)
    """Max number of threads in the thread pool"""

    listeners = Array(ListenerConfig)
Esempio n. 6
0
class ListenerConfig(ComplexModel):
    id = Unicode
    """Name of the listener resource."""

    host = Unicode(default='127.0.0.1')
    """The host the server will listen to"""

    port = UnsignedInteger(default=5534)
    """The port the server will listen to"""

    thread_min = UnsignedInteger
    """Min number of threads in the thread pool"""

    thread_max = UnsignedInteger
    """Max number of threads in the thread pool"""
Esempio n. 7
0
File: core.py Progetto: plq/jmapd
class CoreCapabilities(ComplexModel):
    _type_info = [
        ('max_size_upload',
         UnsignedInteger(
             subname='maxSizeUpload',
             doc="The maximum file size, in octets, that the server will "
             "accept for a single file upload (for any purpose). Suggested "
             "minimum: 50,000,000.")),
        ('max_concurrent_upload',
         UnsignedInteger(
             subname='maxConcurrentUpload',
             doc="The maximum number of concurrent requests the server will "
             "accept to the upload endpoint. Suggested minimum: 4.")),
        ('max_size_request',
         UnsignedInteger(
             subname='maxSizeRequest',
             doc="The maximum size, in octets, that the server will accept for "
             "a single request to the API endpoint. Suggested minimum: 10,"
             "000,000.")),
        ('max_concurrent_requests',
         UnsignedInteger(
             subname='maxConcurrentRequests',
             doc="The maximum number of concurrent requests the server will "
             "accept to the API endpoint. Suggested minimum: 4.")),
        ('max_calls_in_request',
         UnsignedInteger(
             subname='maxCallsInRequest',
             doc="The maximum number of method calls the server will accept in "
             "a single request to the API endpoint. Suggested minimum: 16.")),
        ('max_objects_in_get',
         UnsignedInteger(
             subname='maxObjectsInGet',
             doc="The maximum number of objects that the client may request in "
             "a single /get type method call. Suggested minimum: 500.")),
        ('max_objects_in_set',
         UnsignedInteger(
             subname='maxObjectsInSet',
             doc="The maximum number of objects the client may send to create, "
             "update, or destroy in a single /set type method call. This "
             "is the combined total, e.g., if the maximum is 10, you could "
             "not create 7 objects and destroy 6, as this would be 13 "
             "actions, which exceeds the limit. Suggested minimum: 500.")),
        ('collation_algorithms',
         Array(Unicode,
               subname='collationAlgorithms',
               doc="A list of identifiers for algorithms registered in the "
               "collation registry, as defined in [@!RFC4790], that the "
               "server supports for sorting when querying records.")),
    ]
Esempio n. 8
0
class DatabaseConfig(ComplexModel):
    name = Unicode
    """Database name. Must be a valid python variable name."""

    type = Unicode(values=['sqlalchemy'])
    """Connection type. Only 'sqlalchemy' is supported."""

    conn_str = Unicode
    """Connection string. See SQLAlchemy docs for more info."""

    pool_size = UnsignedInteger(default=10)
    """Max. number of connections in the the db conn pool."""

    show_queries = Boolean(default=False)
    """Logs sql queries."""

    show_results = Boolean(default=False)
    """Logs sql queries as well as their results."""
Esempio n. 9
0
File: core.py Progetto: plq/jmapd
class MailCapabilities(ComplexModel):
    _type_info = [
        ('max_mailboxes_per_email',
         UnsignedInteger(
             sub_name='maxMailboxesPerEmail',
             doc="The maximum number of Mailboxes (see "
             "Section 2) that can be can assigned to a single Email "
             "object (see Section 4). This MUST be an integer >= 1, "
             "or null for no limit (or rather, the limit is always the "
             "number of Mailboxes in the account).")),
        ('max_mailbox_depth',
         UnsignedInteger(
             sub_name='maxMailboxDepth',
             doc="The maximum depth of the Mailbox hierarchy "
             "(i.e., one more than the maximum number of ancestors a "
             "Mailbox may have), or null for no limit.")),
        ('max_size_mailbox_name',
         M(
             UnsignedInteger(
                 sub_name='maxSizeMailboxName',
                 doc="The maximum length, in (UTF-8) octets, allowed "
                 "for the name of a Mailbox. This MUST be at least 100, "
                 "although it is recommended servers allow more."))),
        ('max_size_attachments_per_email',
         M(
             UnsignedInteger(
                 sub_name='maxSizeAttachmentsPerEmail',
                 doc="The maximum total size of attachments, "
                 "in octets, allowed for a single Email object. A server MAY "
                 "still reject the import or creation of an Email with a "
                 "lower attachment size total (for example, if the body "
                 "includes several megabytes of text, causing the size of the "
                 "encoded MIME structure to be over some server-defined "
                 "limit).\n\n"
                 "Note that this limit is for the sum of unencoded attachment "
                 "sizes. Users are generally not knowledgeable about encoding "
                 "overhead, etc., nor should they need to be, so marketing "
                 "and help materials normally tell them the “max size "
                 "attachments”. This is the unencoded size they see on their "
                 "hard drive, so this capability matches that and allows the "
                 "client to consistently enforce what the user understands as "
                 "the limit.\n\n"
                 "The server may separately have a limit for the total size "
                 "of the message [@!RFC5322], created by combining the "
                 "attachments (often base64 encoded) with the message headers "
                 "and bodies. For example, suppose the server advertises "
                 "maxSizeAttachmentsPerEmail: 50000000 (50 MB). The enforced "
                 "server limit may be for a message size of 70000000 octets. "
                 "Even with base64 encoding and a 2 MB HTML body, "
                 "50 MB attachments would fit under this limit."))),
        ('email_query_sort_options',
         Array(Unicode,
               sub_name='emailQuerySortOptions',
               doc="A list of all the values the server supports for "
               "the “property” field of the Comparator object in an "
               "Email/query sort (see Section 4.4.2). This MAY include "
               "properties the client does not recognise (for example, "
               "custom properties specified in a vendor extension). Clients "
               "MUST ignore any unknown properties in the list.")),
        ('may_create_top_level_mailbox',
         Boolean(sub_name='mayCreateTopLevelMailbox',
                 doc="If true, the user may create a Mailbox (see Section "
                 "2) in this account with a null parentId. (Permission for "
                 "creating a child of an existing Mailbox is given by the "
                 "myRights property on that Mailbox.)")),
    ]
Esempio n. 10
0
File: mail.py Progetto: plq/jmapd
class EmailBodyPart(ComplexModel):
    _type_info = [
        ('part_id', Unicode(
            sub_name='partId',
            doc="Identifies this part uniquely within the Email. This is "
                "scoped to the emailId and has no meaning outside of the "
                "JMAP Email object representation. This is null if, and only "
                "if, the part is of type multipart."
        )),

        ('blob_id', JmapId(
            sub_name='blobId',
            doc="Id|null The id representing the raw octets of the contents "
                "of the part, after decoding any known "
                "Content-Transfer-Encoding (as defined in [@!RFC2045]), or "
                "null if, and only if, the part is of type multipart. Note "
                "that two parts may be transfer-encoded differently but have "
                "the same blob id if their decoded octets are identical and "
                "the server is using a secure hash of the data for the blob "
                "id. If the transfer encoding is unknown, it is treated as "
                "though it had no transfer encoding."
        )),

        ('size', M(UnsignedInteger(
            sub_name='size',
            doc="UnsignedInt The size, in octets, of the raw data after "
                "content transfer decoding (as referenced by the blobId, "
                "i.e., the number of octets in the file the user would "
                "download)."
        ))),

        ('headers', Array(EmailHeader,
            sub_name='headers',
            doc="This is a list of all header fields in the "
                "part, in the order they appear in the message. The values "
                "are in Raw form."
        )),

        ('name', Unicode(
            sub_name='name',
            doc="This is the decoded filename parameter of the "
                "Content-Disposition header field per [@!RFC2231], or (for "
                "compatibility with existing systems) if not present, "
                "then it’s the decoded name parameter of the Content-Type "
                "header field per [@!RFC2047]."
        )),

        ('type', M(Unicode(
            sub_name='type',
            doc='String The value of the Content-Type header field of the '
                'part, if present; otherwise, the implicit type as per the '
                'MIME standard (text/plain or message/rfc822 if inside a '
                'multipart/digest). CFWS is removed and any parameters are '
                'stripped.'
        ))),

        ('charset', Unicode(
            sub_name='charset',
            doc="The value of the charset parameter of the Content-Type "
                "header field, if present, or null if the header field is "
                "present but not of type text. If there is no Content-Type "
                "header field, or it exists and is of type text but has no "
                "charset parameter, this is the implicit charset as per the "
                "MIME standard: us-ascii."
        )),

        ('disposition', Unicode(
            sub_name='disposition',
            doc="The value of the Content-Disposition header "
                "field of the part, if present; otherwise, it’s null. CFWS is "
                "removed and any parameters are stripped."
        )),

        ('cid', Unicode(
            sub_name='cid',
            doc="The value of the Content-Id header field of the "
                "part, if present; otherwise it’s null. CFWS and surrounding "
                "angle brackets (<>) are removed. This may be used to "
                "reference the content from within a text/html body part HTML "
                "using the cid: protocol, as defined in [@!RFC2392]."
        )),

        ('language', Array(Unicode,
            sub_name='language',
            doc="The list of language tags, as defined in ["
                "@!RFC3282], in the Content-Language header field of the "
                "part, if present."
        )),

        ('location', Unicode(
            sub_name='location',
            doc="The URI, as defined in [@!RFC2557], in the "
                "Content-Location header field of the part, if present."
        )),

        ('subParts', Array(SelfReference,
            sub_name='subParts',
            doc="If the type is multipart, this contains the body parts of "
                "each child."
        )),
    ]
Esempio n. 11
0
File: mail.py Progetto: plq/jmapd
class Email(ComplexModel):
    _type_info = [
        #
        # Metadata
        #

        ('id', JmapId(
            sub_name='id',
            doc="(immutable; server-set) The id of the Email object. Note "
                "that this is the JMAP object id, NOT the Message-ID header "
                "field value of the message [@!RFC5322]."
        )),

        ('blob_id', JmapId(
            sub_name='blobId',
            doc="(immutable; server-set) The id representing the raw "
                "octets of the message [@!RFC5322] for this Email. This may "
                "be used to download the raw original message or to attach it "
                "directly to another Email, etc."
        )),

        ('thread_id', JmapId(
            sub_name='threadId',
            doc="(immutable; server-set) The id of the Thread to which "
                "this Email belongs."
        )),

        ('mailbox_ids', AnyDict(  # this is supposed to be a JmapId: bool dict
            sub_name='mailboxIds',
            doc="The set of Mailbox ids this Email belongs to. An "
                "Email in the mail store MUST belong to one or more Mailboxes "
                "at all times (until it is destroyed). The set is represented "
                "as an object, with each key being a Mailbox id. The value "
                "for each key in the object MUST be true."
        )),

        ('keywords', AnyDict(  # this is supposed to be a str: bool dict
            sub_name='keywords',
            doc="(default: {}) A set of keywords that apply "
                "to the Email. The set is represented as an object, with the "
                "keys being the keywords. The value for each key in the "
                "object MUST be true."
        )),

        ('size', UnsignedInteger(
            sub_name='size',
            doc="(immutable; server-set) The size, in octets, "
                "of the raw data for the message [@!RFC5322] (as referenced "
                "by the blobId, i.e., the number of octets in the file the "
                "user would download)."
        )),

        ('received_at', UtcDate(
            default_factory=lambda: datetime.utcnow().replace(tzinfo=pytz.utc)
                                                                   .isoformat(),
            sub_name='receivedAt',
            doc="(immutable; default: time of creation on server) The "
                "date the Email was received by the message store. This is "
                "the internal date in IMAP [@?RFC3501]."
        )),

        #
        # Header fields
        #

        ('message_id', Array(Unicode,
            sub_name='messageId',
            doc="(immutable) The value is identical to the "
                "value of header:Message-ID:asMessageIds. For messages "
                "conforming to RFC 5322 this will be an array with a single "
                "entry."
        )),

        ('in_reply_to', Array(Unicode,
            sub_name='inReplyTo',
            doc="(immutable) The value is identical to the "
                "value of header:In-Reply-To:asMessageIds."
        )),

        ('references', Array(Unicode,
            sub_name='references',
            doc="(immutable) The value is identical to the "
                "value of header:References:asMessageIds."
        )),

        ('sender', Array(EmailAddress,
            sub_name='sender',
            doc="(immutable) The value is identical to "
                "the value of header:Sender:asAddresses."
        )),

        ('from_', Array(Unicode,
            sub_name='from',
            doc="(immutable) The value is identical to "
                "the value of header:From:asAddresses."
        )),

        ('to', Array(Unicode,
            sub_name='to',
            doc="(immutable) The value is identical to "
                "the value of header:To:asAddresses."
        )),

        ('cc', Array(Unicode,
            sub_name='cc',
            doc="(immutable) The value is identical to "
                "the value of header:Cc:asAddresses."
        )),

        ('bcc', Array(Unicode,
            sub_name='bcc',
            doc="(immutable) The value is identical to "
                "the value of header:Bcc:asAddresses."
        )),

        ('reply_to', Unicode(
            sub_name='replyTo',
            doc="(immutable) The value is identical to "
                "the value of header:Reply-To:asAddresses."
        )),

        ('subject', Unicode(
            sub_name='subject',
            doc="(immutable) The value is identical to the value "
                "of header:Subject:asText."
        )),

        ('sent_at', DateTime(
            sub_name='sentAt',
            doc="(immutable; default on creation: current server "
                "time) The value is identical to the value of "
                "header:Date:asDate."
        )),

        #
        # Body Parts
        #

        ('body_structure', Array(EmailBodyPart,
            sub_name='bodyStructure',
            doc="(immutable) This is the full MIME structure of the message "
                "body, without recursing into message/rfc822 or message/global "
                "parts. Note that EmailBodyParts may have subParts if they "
                "are of type multipart."
        )),

        ('body_values', AnyDict(
            sub_name='bodyValues',
            doc="(immutable) This is a map of partId to an EmailBodyValue "
                "object for none, some, or all text parts. Which parts are "
                "included and whether the value is truncated is determined "
                "by various arguments to Email/get and Email/parse."
        )),

        ('text_body', Array(EmailBodyPart,
            sub_name='textBody',
            doc="(immutable) A list of text/plain, text/html, image, audio, "
                "and/or video parts to display (sequentially) as the message "
                "body, with a preference for text/plain when alternative "
                "versions are available."
        )),

        ('html_body', Array(EmailBodyPart,
            sub_name='htmlBody',
            doc="(immutable) A list of text/plain, text/html, image, audio, "
                "and/or video parts to display (sequentially) as the message "
                "body, with a preference for text/html when alternative "
                "versions are available."
        )),

        ('attachments', Array(EmailBodyPart,
            sub_name='attachments',
            doc="(immutable) A list, traversing depth-first, "
                "of all parts in bodyStructure that satisfy either of the "
                "following conditions:"
        )),

        ('has_attachment', M(Boolean(
            sub_name='hasAttachment', default=False,
            doc="(immutable; server-set) This is true if there are "
                "one or more parts in the message that a client UI should "
                "offer as downloadable. A server SHOULD set hasAttachment to "
                "true if the attachments list contains at least one item that "
                "does not have Content-Disposition: inline. The server MAY "
                "ignore parts in this list that are processed automatically "
                "in some way or are referenced as embedded images in one of "
                "the text/html parts of the message."
        ))),

        ('preview', Unicode(256,
            sub_name='preview', default=u'',
            doc="(immutable; server-set) A plaintext fragment of the "
                "message body. This is intended to be shown as a preview line "
                "when listing messages in the mail store and may be truncated "
                "when shown. The server may choose which part of the message "
                "to include in the preview; skipping quoted sections and "
                "salutations and collapsing white space can result in a more "
                "useful preview."
        )),
    ]