This commit is contained in:
Tobias Oberstein 2017-03-19 22:23:08 +01:00
parent ff481ce649
commit e485dc4cdd
10 changed files with 160 additions and 62 deletions

View File

@ -24,4 +24,4 @@
#
###############################################################################
__version__ = u'0.17.3'
__version__ = u'0.18.0'

View File

@ -45,6 +45,7 @@ import txaio
__all__ = ("public",
"encode_truncate",
"xor",
"utcnow",
"utcstr",
@ -83,13 +84,18 @@ def encode_truncate(text, limit, encoding='utf8', return_encoded=True):
points that encode to multi-byte encodings which must not be truncated
in the middle.
:param text: The Unicode string to truncate.
:type text: unicode
:param text: The (Unicode) string to truncate.
:type text: str
:param limit: The number of bytes to limit the UTF8 encoding to.
:type limit: int
:param encoding: Truncate the string in this encoding (default is ``utf-8``).
:type encoding: str
:param return_encoded: If ``True``, return the string encoded into bytes
according to the specified encoding, else return the string as a string.
:type return_encoded: bool
:returns: The truncated Unicode string.
:rtype: unicode
:returns: The truncated string.
:rtype: str or bytes
"""
assert(text is None or type(text) == six.text_type)
assert(type(limit) in six.integer_types)
@ -129,8 +135,8 @@ def xor(d1, d2):
:param d2: The second binary string.
:type d2: binary
:returns: XOR(d1, d2)
:rtype: binary
:returns: XOR of the binary strings (``XOR(d1, d2)``)
:rtype: bytes
"""
if type(d1) != six.binary_type:
raise Exception("invalid type {} for d1 - must be binary".format(type(d1)))
@ -160,10 +166,10 @@ def utcstr(ts=None):
module instead (e.g. ``iso8601.parse_date("2014-05-23T13:03:44.123Z")``).
:param ts: The timestamp to format.
:type ts: instance of :py:class:`datetime.datetime` or None
:type ts: instance of :py:class:`datetime.datetime` or ``None``
:returns: Timestamp formatted in ISO 8601 format.
:rtype: unicode
:rtype: str
"""
assert(ts is None or isinstance(ts, datetime))
if ts is None:
@ -177,7 +183,7 @@ def utcnow():
Get current time in UTC as ISO 8601 string.
:returns: Current time as string in ISO 8601 format.
:rtype: unicode
:rtype: str
"""
return utcstr()
@ -306,7 +312,7 @@ def newid(length=16):
:type length: int
:returns: A random string ID.
:rtype: unicode
:rtype: str
"""
l = int(math.ceil(float(length) * 6. / 8.))
return base64.b64encode(os.urandom(l))[:length].decode('ascii')
@ -324,8 +330,6 @@ Default set of characters to create rtokens from.
DEFAULT_ZBASE32_CHARS = u'13456789abcdefghijkmnopqrstuwxyz'
"""
http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
Our choice of confusing characters to eliminate is: `0', `l', `v', and `2'. Our
reasoning is that `0' is potentially mistaken for `o', that `l' is potentially
mistaken for `1' or `i', that `v' is potentially mistaken for `u' or `r'
@ -336,6 +340,8 @@ Note that we choose to focus on typed and written transcription more than on
vocal, since humans already have a well-established system of disambiguating
spoken alphanumerics, such as the United States military's "Alpha Bravo Charlie
Delta" and telephone operators' "Is that 'd' as in 'dog'?".
* http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
"""
@ -345,40 +351,48 @@ def generate_token(char_groups, chars_per_group, chars=None, sep=None, lower_cas
Generate cryptographically strong tokens, which are strings like `M6X5-YO5W-T5IK`.
These can be used e.g. for used-only-once activation tokens or the like.
The returned token has an entropy of:
The returned token has an entropy of
``math.log(len(chars), 2.) * chars_per_group * char_groups``
bits.
math.log(len(chars), 2.) * chars_per_group * char_groups
With the default charset and 4 characters per group, ``generate_token()`` produces
strings with the following entropy:
bits. With the default charset and 4 characters per group, rtoken() produces
tokens with the following entropy:
================ =================== ========================================
character groups entropy (at least) recommended use
================ =================== ========================================
2 38 bits
3 57 bits one-time activation or pairing code
4 76 bits secure user password
5 95 bits
6 114 bits globally unique serial / product code
7 133 bits
================ =================== ========================================
character groups entropy (at least) recommended use
Here are some examples:
2 38 bits
3 57 bits one-time activation or pairing code
4 76 bits secure user password
5 95 bits
6 114 bits globally unique serial / product code
7 133 bits
Here are 3 examples:
* token(3): 9QXT-UXJW-7R4H
* token(4): LPNN-JMET-KWEP-YK45
* token(6): NXW9-74LU-6NUH-VLPV-X6AG-QUE3
* token(3): ``9QXT-UXJW-7R4H``
* token(4): ``LPNN-JMET-KWEP-YK45``
* token(6): ``NXW9-74LU-6NUH-VLPV-X6AG-QUE3``
:param char_groups: Number of character groups (or characters if chars_per_group == 1).
:type char_groups: int
:param chars_per_group: Number of characters per character group (or 1 to return a token with no grouping).
:type chars_per_group: int
:param chars: Characters to choose from. Default is 27 character subset
of the ISO basic Latin alphabet (see: DEFAULT_TOKEN_CHARS).
:type chars: unicode or None
of the ISO basic Latin alphabet (see: ``DEFAULT_TOKEN_CHARS``).
:type chars: str or None
:param sep: When separating groups in the token, the separater string.
:type sep: unicode
:type sep: str
:param lower_case: If ``True``, generate token in lower-case.
:type lower_case: bool
:returns: The generated token.
:rtype: unicode
:rtype: str
"""
assert(type(char_groups) in six.integer_types)
assert(type(chars_per_group) in six.integer_types)
@ -397,16 +411,37 @@ def generate_token(char_groups, chars_per_group, chars=None, sep=None, lower_cas
@public
def generate_activation_code():
"""
Generate a one-time activation code or token of the form ``u'W97F-96MJ-YGJL'``.
The generated value is cryptographically strong and has (at least) 57 bits of entropy.
:returns: The generated activation code.
:rtype: str
"""
return generate_token(char_groups=3, chars_per_group=4, chars=DEFAULT_TOKEN_CHARS, sep=u'-', lower_case=False)
@public
def generate_user_password():
"""
Generate a secure, random user password of the form ``u'kgojzi61dn5dtb6d'``.
The generated value is cryptographically strong and has (at least) 76 bits of entropy.
:returns: The generated password.
:rtype: str
"""
return generate_token(char_groups=16, chars_per_group=1, chars=DEFAULT_ZBASE32_CHARS, sep=u'-', lower_case=True)
@public
def generate_serial_number():
"""
Generate a globally unique serial / product code of the form ``u'YRAC-EL4X-FQQE-AW4T-WNUV-VN6T'``.
The generated value is cryptographically strong and has (at least) 114 bits of entropy.
:returns: The generated serial number / product code.
:rtype: str
"""
return generate_token(char_groups=6, chars_per_group=4, chars=DEFAULT_TOKEN_CHARS, sep=u'-', lower_case=False)
@ -428,14 +463,16 @@ else:
_rtime = time.time
rtime = _rtime
"""
Precise wallclock time.
@public
def rtime():
"""
Precise, fast wallclock time.
:returns: The current wallclock in seconds. Returned values are only guaranteed
to be meaningful relative to each other.
:rtype: float
"""
:returns: The current wallclock in seconds. Returned values are only guaranteed
to be meaningful relative to each other.
:rtype: float
"""
return _rtime()
class Stopwatch(object):
@ -449,6 +486,7 @@ class Stopwatch(object):
def __init__(self, start=True):
"""
:param start: If ``True``, immediately start the stopwatch.
:type start: bool
"""

View File

@ -27,6 +27,7 @@
from __future__ import absolute_import
from autobahn.wamp.types import \
ComponentConfig, \
SessionDetails, \
CloseDetails, \
RegisterOptions, \
@ -57,6 +58,7 @@ from autobahn.wamp.uri import \
__all__ = (
'ComponentConfig',
'SessionDetails',
'CloseDetails',
'RegisterOptions',

View File

@ -86,7 +86,7 @@ def _read_ssh_ed25519_pubkey(keydata):
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJukDU5fqXv/yVhSirsDWsUFyOodZyCSLxyitPPzWJW9 oberstet@office-corei7
:param keydata: The OpenSSH Ed25519 public key data to parse.
:type keydata: unicode
:type keydata: str
:returns: pair of raw public key (32 bytes) and comment
:rtype: tuple
@ -159,7 +159,7 @@ def _read_ssh_ed25519_privkey(keydata):
:param keydata: The OpenSSH Ed25519 private key data to parse.
:type keydata: unicode
:type keydata: str
:returns: pair of raw private key (32 bytes) and comment
:rtype: tuple
@ -395,7 +395,7 @@ if HAS_CRYPTOSIGN:
Get the key comment (if any).
:returns: The comment (if any) from the key.
:rtype: unicode or None
:rtype: str or None
"""
return self._comment
@ -405,7 +405,7 @@ if HAS_CRYPTOSIGN:
Returns the public key part of a signing key or the (public) verification key.
:returns: The public key in Hex encoding.
:rtype: unicode or None
:rtype: str or None
"""
if isinstance(self._key, signing.SigningKey):
key = self._key.verify_key
@ -452,7 +452,7 @@ if HAS_CRYPTOSIGN:
:type challenge: instance of autobahn.wamp.types.Challenge
:returns: A Deferred/Future that resolves to the computed signature.
:rtype: unicode
:rtype: str
"""
if not isinstance(challenge, Challenge):
raise Exception("challenge must be instance of autobahn.wamp.types.Challenge, not {}".format(type(challenge)))
@ -509,9 +509,9 @@ if HAS_CRYPTOSIGN:
dd if=/dev/urandom of=client02.key bs=1 count=32
:param filename: Filename of the key.
:type filename: unicode
:type filename: str
:param comment: Comment for key (optional).
:type comment: unicode or None
:type comment: str or None
"""
if not (comment is None or type(comment) == six.text_type):
raise Exception("invalid type {} for comment".format(type(comment)))

View File

@ -216,16 +216,26 @@ class ApplicationError(Error):
exclusion of (any) *Callee* providing the procedure (WAMP AP).
"""
# application payload end-to-end encryption related errors
ENC_NO_KEYRING_ACTIVE = u"wamp.error.encryption.no_keyring_active"
"""
WAMP-cryptobox application payload end-to-end encryption error.
"""
ENC_TRUSTED_URI_MISMATCH = u"wamp.error.encryption.trusted_uri_mismatch"
"""
WAMP-cryptobox application payload end-to-end encryption error.
"""
ENC_DECRYPT_ERROR = u"wamp.error.encryption.decrypt_error"
"""
WAMP-cryptobox application payload end-to-end encryption error.
"""
def __init__(self, error, *args, **kwargs):
"""
:param error: The URI of the error that occurred, e.g. ``wamp.error.not_authorized``.
:type error: unicode
:type error: str
"""
Exception.__init__(self, *args)
self.kwargs = kwargs
@ -237,7 +247,8 @@ class ApplicationError(Error):
"""
Get the error message of this exception.
:return: unicode
:returns: The error message.
:rtype: str
"""
return u'{0}: {1}'.format(
self.error,

View File

@ -70,22 +70,26 @@ class ComponentConfig(object):
:param realm: The realm the session would like to join or ``None`` to let the router
auto-decide the realm (if the router is configured and allowing to do so).
:type realm: str
:param extra: Optional user-supplied object with extra configuration.
This can be any object you like, and is accessible in your
`ApplicationSession` subclass via `self.config.extra`. `dict` is
a good default choice. Important: if the component is to be hosted
by Crossbar.io, the supplied value must be JSON serializable.
:type extra: arbitrary
:param keyring: A mapper from WAMP URIs to "from"/"to" Ed25519 keys. When using
WAMP end-to-end encryption, application payload is encrypted using a
symmetric message key, which in turn is encrypted using the "to" URI (topic being
published to or procedure being called) public key and the "from" URI
private key. In both cases, the key for the longest matching URI is used.
:type keyring: obj implementing IKeyRing or None
:param controller: A WAMP ApplicationSession instance that holds a session to
a controlling entity. This optional feature needs to be supported by a WAMP
component hosting run-time.
:type controller: instance of ApplicationSession or None
:param shared: A dict object to exchange user information or hold user objects shared
between components run under the same controlling entity. This optional feature
needs to be supported by a WAMP component hosting run-time. Use with caution, as using
@ -133,14 +137,19 @@ class Accept(HelloReturn):
:param realm: The realm the client is joined to.
:type realm: str
:param authid: The authentication ID the client is assigned, e.g. ``"joe"`` or ``"joe@example.com"``.
:type authid: str
:param authrole: The authentication role the client is assigned, e.g. ``"anonymous"``, ``"user"`` or ``"com.myapp.user"``.
:type authrole: str
:param authmethod: The authentication method that was used to authenticate the client, e.g. ``"cookie"`` or ``"wampcra"``.
:type authmethod: str
:param authprovider: The authentication provider that was used to authenticate the client, e.g. ``"mozilla-persona"``.
:type authprovider: str
:param authextra: Application-specific authextra to be forwarded to the client in `WELCOME.details.authextra`.
:type authextra: dict
"""
@ -178,6 +187,7 @@ class Deny(HelloReturn):
:param reason: The reason of denying the authentication (an URI, e.g. ``u'wamp.error.not_authorized'``)
:type reason: str
:param message: A human readable message (for logging purposes).
:type message: str
"""
@ -246,21 +256,31 @@ class HelloDetails(object):
:param realm: The realm the client wants to join.
:type realm: str or None
:param authmethods: The authentication methods the client is willing to perform.
:type authmethods: list of str or None
:param authid: The authid the client wants to authenticate as.
:type authid: str or None
:param authrole: The authrole the client wants to authenticate as.
:type authrole: str or None
:param authextra: Any extra information the specific authentication method requires the client to send.
:type authextra: arbitrary or None
:param session_roles: The WAMP session roles and features by the connecting client.
:type session_roles: dict or None
:param pending_session: The session ID the session will get once successfully attached.
:type pending_session: int or None
:param resumable:
:type resumable: bool or None
:param resume_session: The session the client would like to resume.
:type resume_session: int or None
:param resume_token: The secure authorisation token to resume the session.
:type resume_token: str or None
"""
@ -316,12 +336,16 @@ class SessionDetails(object):
:param realm: The realm this WAMP session is attached to.
:type realm: str
:param session: WAMP session ID of this session.
:type session: int
:param resumed: Whether the session is a resumed one.
:type resumed: bool or None
:param resumable: Whether this session can be resumed later.
:type resumable: bool or None
:param resume_token: The secure authorisation token to resume the session.
:type resume_token: str or None
"""
@ -371,6 +395,7 @@ class CloseDetails(object):
:param reason: The close reason (an URI, e.g. ``wamp.close.normal``)
:type reason: str
:param message: Closing log message.
:type message: str
"""
@ -402,9 +427,11 @@ class SubscribeOptions(object):
:param match: The topic matching method to be used for the subscription.
:type match: str
:param details_arg: When invoking the handler, provide event details
in this keyword argument to the callable.
:type details_arg: str
:param get_retained: Whether the client wants the retained message we may have along with the subscription.
:type get_retained: bool or None
"""
@ -456,20 +483,26 @@ class EventDetails(object):
:param publication: The publication ID of the event (always present).
:type publication: int
:param publisher: The WAMP session ID of the original publisher of this event.
Only filled when publisher is disclosed.
:type publisher: None or int
:param publisher_authid: The WAMP authid of the original publisher of this event.
Only filled when publisher is disclosed.
:type publisher_authid: None or str
:param publisher_authrole: The WAMP authrole of the original publisher of this event.
Only filled when publisher is disclosed.
:type publisher_authrole: None or str
:param topic: For pattern-based subscriptions, the actual topic URI being published to.
Only filled for pattern-based subscriptions.
:type topic: None or str
:param retained: Whether the message was retained by the broker on the topic, rather than just published.
:type retained: bool or None
:param enc_algo: Payload encryption algorithm that
was in use (currently, either ``None`` or ``u'cryptobox'``).
:type enc_algo: None or str
@ -528,21 +561,29 @@ class PublishOptions(object):
:param acknowledge: If ``True``, acknowledge the publication with a success or
error response.
:type acknowledge: bool
:param exclude_me: If ``True``, exclude the publisher from receiving the event, even
if he is subscribed (and eligible).
:type exclude_me: bool or None
:param exclude: A single WAMP session ID or a list thereof to exclude from receiving this event.
:type exclude: int or list of int or None
:param exclude_authid: A single WAMP authid or a list thereof to exclude from receiving this event.
:type exclude_authid: str or list of str or None
:param exclude_authrole: A single WAMP authrole or a list thereof to exclude from receiving this event.
:type exclude_authrole: list of str or None
:param eligible: A single WAMP session ID or a list thereof eligible to receive this event.
:type eligible: int or list of int or None
:param eligible_authid: A single WAMP authid or a list thereof eligible to receive this event.
:type eligible_authid: str or list of str or None
:param eligible_authrole: A single WAMP authrole or a list thereof eligible to receive this event.
:type eligible_authrole: str or list of str or None
:param retain: If ``True``, request the broker retain this event.
:type retain: bool or None
"""
@ -678,17 +719,22 @@ class CallDetails(object):
:param progress: A callable that will receive progressive call results.
:type progress: callable
:param caller: The WAMP session ID of the caller, if the latter is disclosed.
Only filled when caller is disclosed.
:type caller: int
:param caller_authid: The WAMP authid of the original caller of this event.
Only filled when caller is disclosed.
:type caller_authid: None or str
:param caller_authrole: The WAMP authrole of the original caller of this event.
Only filled when caller is disclosed.
:type caller_authrole: None or str
:param procedure: For pattern-based registrations, the actual procedure URI being called.
:type procedure: None or str
:param enc_algo: Payload encryption algorithm that
was in use (currently, either `None` or `"cryptobox"`).
:type enc_algo: None or str
@ -730,6 +776,7 @@ class CallOptions(object):
:param on_progress: A callback that will be called when the remote endpoint
called yields interim call progress results.
:type on_progress: callable
:param timeout: Time in seconds after which the call should be automatically canceled.
:type timeout: float
"""
@ -775,6 +822,7 @@ class CallResult(object):
:param results: The positional result values.
:type results: list
:param kwresults: The keyword result values.
:type kwresults: dict
"""

View File

@ -2424,6 +2424,8 @@ class WebSocketServerProtocol(WebSocketProtocol):
Protocol base class for WebSocket servers.
"""
log = txaio.make_logger()
CONFIG_ATTRS = WebSocketProtocol.CONFIG_ATTRS_COMMON + WebSocketProtocol.CONFIG_ATTRS_SERVER
def onConnect(self, request):
@ -3058,6 +3060,8 @@ class WebSocketServerFactory(WebSocketFactory):
A protocol factory for WebSocket servers.
"""
log = txaio.make_logger()
protocol = WebSocketServerProtocol
"""
The protocol to be spoken. Must be derived from :class:`autobahn.websocket.protocol.WebSocketServerProtocol`.
@ -3374,6 +3378,8 @@ class WebSocketClientProtocol(WebSocketProtocol):
Protocol base class for WebSocket clients.
"""
log = txaio.make_logger()
CONFIG_ATTRS = WebSocketProtocol.CONFIG_ATTRS_COMMON + WebSocketProtocol.CONFIG_ATTRS_CLIENT
def onConnect(self, response):
@ -3822,6 +3828,8 @@ class WebSocketClientFactory(WebSocketFactory):
A protocol factory for WebSocket clients.
"""
log = txaio.make_logger()
protocol = WebSocketClientProtocol
"""
The protocol to be spoken. Must be derived from :class:`autobahn.websocket.protocol.WebSocketClientProtocol`.

View File

@ -5,10 +5,10 @@
Changelog
=========
0.17.3
0.18.0
------
`Published 2017-03-18 <https://pypi.python.org/pypi/autobahn/0.17.3>`__
`Published 2017-03-19 <https://pypi.python.org/pypi/autobahn/0.18.0>`__
* fix: docs for publisher black-/whitelisting based on authid/authrole
* fix: serialization for publisher black-/whitelisting based on authid/authrole

View File

@ -41,7 +41,6 @@ autobahn.wamp.protocol
.. automodule:: autobahn.wamp.protocol
:members:
:undoc-members:
:show-inheritance:
autobahn.wamp.role

View File

@ -9,7 +9,6 @@ autobahn.websocket.compress
.. automodule:: autobahn.websocket.compress
:members:
:undoc-members:
:show-inheritance:
autobahn.websocket.compress_base
@ -17,7 +16,6 @@ autobahn.websocket.compress_base
.. automodule:: autobahn.websocket.compress_base
:members:
:undoc-members:
:show-inheritance:
autobahn.websocket.compress_deflate
@ -25,7 +23,6 @@ autobahn.websocket.compress_deflate
.. automodule:: autobahn.websocket.compress_deflate
:members:
:undoc-members:
:show-inheritance:
autobahn.websocket.interfaces
@ -33,7 +30,6 @@ autobahn.websocket.interfaces
.. automodule:: autobahn.websocket.interfaces
:members:
:undoc-members:
:show-inheritance:
autobahn.websocket.protocol
@ -41,7 +37,6 @@ autobahn.websocket.protocol
.. automodule:: autobahn.websocket.protocol
:members:
:undoc-members:
:show-inheritance:
autobahn.websocket.utf8validator
@ -49,7 +44,6 @@ autobahn.websocket.utf8validator
.. automodule:: autobahn.websocket.utf8validator
:members:
:undoc-members:
:show-inheritance:
autobahn.websocket.xormasker
@ -57,7 +51,6 @@ autobahn.websocket.xormasker
.. automodule:: autobahn.websocket.xormasker
:members:
:undoc-members:
:show-inheritance:
@ -66,5 +59,4 @@ Module contents
.. automodule:: autobahn.websocket
:members:
:undoc-members:
:show-inheritance: