<commit_before>#
# (C) Copyright 2011 <NAME> <<EMAIL>>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License Version
# 2.1 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# pylint: disable-msg=W0201

"""Resource binding implementation.

Normative reference:
  - `RFC 6120 <http://www.ietf.org/rfc/rfc3920.txt>`__
"""

from __future__ import absolute_import

__docformat__ = "restructuredtext en"

import logging
import uuid

from xml.etree import ElementTree

from .constants import BIND_QNP
from .stanzapayload import StanzaPayload, payload_element_name
from .streambase import StreamFeatureHandler
from .stanzaprocessor import XMPPFeatureHandler
from .stanzaprocessor import iq_set_stanza_handler
from .settings import XMPPSettings
from .streamevents import BindingResourceEvent, AuthorizedEvent
from .exceptions import ResourceConstraintProtocolError, JIDError
from .exceptions import BadRequestProtocolError, FatalStreamError
from .iq import Iq
from .jid import JID

logger = logging.getLogger("pyxmpp.binding")


FEATURE_BIND = BIND_QNP + u"bind"
BIND_JID_TAG = BIND_QNP + u"jid"
BIND_RESOURCE_TAG = BIND_QNP + u"resource"

@payload_element_name(FEATURE_BIND)
class ResourceBindingPayload(StanzaPayload):
    """Resource binding <iq/> stanza payload.
    
    :Ivariables:
        - `jid`: content of the <jid/> child element
        - `resource`: content of the <resource/> child element
    :Types:
        - `jid`: `JID`
        - `resource`: `unicode`
    """
    def __init__(self, element = None, jid = None, resource = None):
        StanzaPayload.__init__(self, element)
        self.jid = None
        self.resource = None
        if element is not None:
            for child in element:
                if child.tag == BIND_JID_TAG:
                    if self.jid:
                        raise BadRequestProtocolError(
                                    "<bind/> contains multiple <jid/> elements")
                    self.jid = JID(child.text)
                if child.tag == BIND_RESOURCE_TAG:
                    if self.resource:
                        raise BadRequestProtocolError(
                                    "<bind/> contains multiple <jid/> elements")
                    self.resource = child.text
        if jid:
            self.jid = jid
        if resource:
            self.resource = resource
    def as_xml(self):
        element = ElementTree.Element(FEATURE_BIND)
        if self.jid:
            sub = ElementTree.SubElement(element, BIND_JID_TAG)
            sub.text = unicode(self.jid)
        if self.resource:
            sub = ElementTree.SubElement(element, BIND_RESOURCE_TAG)
            sub.text = self.resource
        return element

class ResourceBindingHandler(StreamFeatureHandler, XMPPFeatureHandler):
    """Resource binding implementation.

    To be used as one of the handlers passed to a stream class
    constructor."""
    def __init__(self, settings = None):
        """Initialize the SASL handler"""
        if settings is None:
            settings = XMPPSettings()

    def make_stream_features(self, stream, features):
        """Add resource binding feature to the <features/> element of the
        stream.

        [receving entity only]

        :returns: update <features/> element node."""
        if stream.peer_authenticated and not stream.peer.resource:
            ElementTree.SubElement(features, FEATURE_BIND)

    def handle_stream_features(self, stream, features):
        """Process incoming <stream:features/> element.

        [initiating entity only]

        The received features node is available in `self.features`."""
        logger.debug("Handling stream features: {0}".format(
                                        ElementTree.tostring(features)))
        element = features.find(FEATURE_BIND)
        if element is None:
            logger.debug("No <bind/> in features")
            return False
        self.bind(stream, stream.me.resource)
        return True

    def bind(self, stream, resource):
        """Bind to a resource.

        [initiating entity only]

        :Parameters:
            - `resource`: the resource name to bind to.
        :Types:
            - `resource`: `unicode`

        XMPP stream is authenticated for bare JID only. To use
        the full JID it must be bound to a resource.
        """
        stanza = Iq(stanza_type = "set")
        payload = ResourceBindingPayload(resource = resource)
        stanza.set_payload(payload)
        stream.set_response_handlers(stanza, 
                                        self._bind_success, self._bind_error)
        stream.send(stanza)
        stream.event(BindingResourceEvent(resource))<commit_msg>Support for the 'resource' setting<commit_after>#
# (C) Copyright 2011 <NAME> <<EMAIL>>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License Version
# 2.1 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# pylint: disable-msg=W0201

"""Resource binding implementation.

Normative reference:
  - `RFC 6120 <http://www.ietf.org/rfc/rfc3920.txt>`__
"""

from __future__ import absolute_import

__docformat__ = "restructuredtext en"

import logging
import uuid

from xml.etree import ElementTree

from .constants import BIND_QNP
from .stanzapayload import StanzaPayload, payload_element_name
from .streambase import StreamFeatureHandler
from .stanzaprocessor import XMPPFeatureHandler
from .stanzaprocessor import iq_set_stanza_handler
from .settings import XMPPSettings
from .streamevents import BindingResourceEvent, AuthorizedEvent
from .exceptions import ResourceConstraintProtocolError, JIDError
from .exceptions import BadRequestProtocolError, FatalStreamError
from .iq import Iq
from .jid import JID

logger = logging.getLogger("pyxmpp.binding")


FEATURE_BIND = BIND_QNP + u"bind"
BIND_JID_TAG = BIND_QNP + u"jid"
BIND_RESOURCE_TAG = BIND_QNP + u"resource"

def default_resource_factory(settings):
    """Factory for the 'resource' setting default: use random uuid"""
    # pylint: disable-msg=W0613
    return unicode(uuid.uuid4())

XMPPSettings.add_default_factory("resource", default_resource_factory)

@payload_element_name(FEATURE_BIND)
class ResourceBindingPayload(StanzaPayload):
    """Resource binding <iq/> stanza payload.
    
    :Ivariables:
        - `jid`: content of the <jid/> child element
        - `resource`: content of the <resource/> child element
    :Types:
        - `jid`: `JID`
        - `resource`: `unicode`
    """
    def __init__(self, element = None, jid = None, resource = None):
        StanzaPayload.__init__(self, element)
        self.jid = None
        self.resource = None
        if element is not None:
            for child in element:
                if child.tag == BIND_JID_TAG:
                    if self.jid:
                        raise BadRequestProtocolError(
                                    "<bind/> contains multiple <jid/> elements")
                    self.jid = JID(child.text)
                if child.tag == BIND_RESOURCE_TAG:
                    if self.resource:
                        raise BadRequestProtocolError(
                                    "<bind/> contains multiple <jid/> elements")
                    self.resource = child.text
        if jid:
            self.jid = jid
        if resource:
            self.resource = resource
    def as_xml(self):
        element = ElementTree.Element(FEATURE_BIND)
        if self.jid:
            sub = ElementTree.SubElement(element, BIND_JID_TAG)
            sub.text = unicode(self.jid)
        if self.resource:
            sub = ElementTree.SubElement(element, BIND_RESOURCE_TAG)
            sub.text = self.resource
        return element

class ResourceBindingHandler(StreamFeatureHandler, XMPPFeatureHandler):
    """Resource binding implementation.

    To be used as one of the handlers passed to a stream class
    constructor."""
    def __init__(self, settings = None):
        """Initialize the SASL handler"""
        if settings is None:
            settings = XMPPSettings()

    def make_stream_features(self, stream, features):
        """Add resource binding feature to the <features/> element of the
        stream.

        [receving entity only]

        :returns: update <features/> element node."""
        if stream.peer_authenticated and not stream.peer.resource:
            ElementTree.SubElement(features, FEATURE_BIND)

    def handle_stream_features(self, stream, features):
        """Process incoming <stream:features/> element.

        [initiating entity only]

        The received features node is available in `self.features`."""
        logger.debug("Handling stream features: {0}".format(
                                        ElementTree.tostring(features)))
        element = features.find(FEATURE_BIND)
        if element is None:
            logger.debug("No <bind/> in features")
            return False
        if stream.me.resource:
            resource = stream.me.resource
        else:
            resource = stream.settings["resource"]
        self.bind(stream, resource)
        return True

    def bind(self, stream, resource):
        """Bind to a resource.

        [initiating entity only]

        :Parameters:
            - `resource`: the resource name to bind to.
        :Types:
            - `resource`: `unicode`

        XMPP stream is authenticated for bare JID only. To use
        the full JID it must be bound to a resource.
        """
        stanza = Iq(stanza_type = "set")
        payload = ResourceBindingPayload(resource = resource)
        stanza.set_payload(payload)
        stream.set_response_handlers(stanza, 
                                        self._bind_success, self._bind_error)
        stream.send(stanza)
        stream.event(BindingResourceEvent(resource))
{'fraction_non_alphanumeric': 0.08107858528026596, 'fraction_numerical': 0.005448333179425616, 'mean_word_length': 2.498062015503876, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2310347', 'n_tokens_mistral': 2970, 'n_tokens_neox': 2866, 'n_words': 943}