Beispiel #1
0
	def test_send(self):
		message = Bunch(id='foo')

		interface = Mailer(base_config)

		with pytest.raises(MailerNotRunning):
			interface.send(message)

		interface.start()

		#logging.getLogger().handlers[0].truncate()
		#messages = logging.getLogger().handlers[0].buffer

		assert interface.send(message) == (message, True)

		#assert messages[0] == "Attempting delivery of message foo."
		#assert messages[-1] == "Message foo delivered."

		message_fail = Bunch(id='bar', die=True)
		
		with pytest.raises(Exception):
			interface.send(message_fail)

		#assert messages[-4] == "Attempting delivery of message bar."
		#assert messages[-3] == "Acquired existing transport instance."
		#assert messages[-2] == "Shutting down transport due to unhandled exception."
		#assert messages[-1] == "Delivery of message bar failed."

		interface.stop()
Beispiel #2
0
 def lookup(cls, identifier):
     uid, credential = identifier
     
     user = cls.objects.with_id(uid)
     
     if not user:
         return None
     
     cred = None
     
     for i in user.credentials:
         if i.identity == credential:
             cred = i
             break
     
     bundle = Bunch(identity=user, credential=cred)
     bundle.effective = [i for i in user.permissions]
     
     for cred in user.credentials:
         if cred.identity == identifier:
             for perm in cred.permissions:
                 if perm.startswith('-'):
                     bundle.effective.remove(perm[1:])
                     break
                 bundle.effective.append(perm)
             break
     
     bundle.permissions = set(bundle.effective)
     
     return bundle
Beispiel #3
0
 def test_send(self):
     message = Bunch(id='foo')
     
     interface = Mailer(base_config)
     
     self.assertRaises(MailerNotRunning, interface.send, message)
     
     interface.start()
     
     logging.getLogger().handlers[0].truncate()
     messages = logging.getLogger().handlers[0].buffer
     
     self.assertEqual(interface.send(message), (message, True))
     
     self.assertEqual(messages[0].getMessage(), "Attempting delivery of message foo.")
     self.assertEqual(messages[-1].getMessage(), "Message foo delivered.")
     
     message_fail = Bunch(id='bar', die=True)
     self.assertRaises(Exception, interface.send, message_fail)
     
     self.assertEqual(messages[-4].getMessage(), "Attempting delivery of message bar.")
     self.assertEqual(messages[-3].getMessage(), "Acquired existing transport instance.")
     self.assertEqual(messages[-2].getMessage(), "Shutting down transport due to unhandled exception.")
     self.assertEqual(messages[-1].getMessage(), "Delivery of message bar failed.")
     
     interface.stop()
Beispiel #4
0
Datei: eve.py Projekt: Acen/core
def bunchify(data, name=None):
    if isinstance(data, Bunch):
        return data
    
    if isinstance(data, list):
        if name == 'rowset':  # we unpack these into a dictionary based on name
            return Bunch({i['name']: bunchify(i, 'rowset') for i in data})
        
        return [bunchify(i) for i in data]
    
    if isinstance(data, dict):
        data = data.copy()
        
        if name == 'row' and 'row' in data:
            # Special case of CCP's silly key:value text.
            pass
        
        if name and name in data and not data.get(name, '').strip():
            data.pop(name)
        
        if name == 'rowset' and 'name' in data:
            data.pop('name')
        
        if len(data) == 1 and isinstance(data.values()[0], dict):
            return bunchify(data.values()[0], data.keys()[0])
        
        result = Bunch({
                k: bunchify(
                        [v] if k in ('row', ) and not isinstance(v, list) else v,
                        k
                    ) for k, v in data.iteritems() if k != 'rowset'
            })
        
        if 'rowset' in data:
            rowset = bunchify(data['rowset'] if isinstance(data['rowset'], list) else [data['rowset']], 'rowset')
            result.update(rowset)
        
        if name == 'rowset':  # rowsets always contain rows, even if there are no results
            result.setdefault('row', [])
        
        return result
    
    if isinstance(data, str):
        data = data.decode('utf-8')
    
    if isinstance(data, (str, unicode)):
        try:
            return number(data)
        except ValueError:
            pass
        
        try:
            return boolean(data)
        except ValueError:
            pass
        
        if ',' in data and (name in ('key', 'columns') or ' ' not in data):
            return array(data)
    
    return data
Beispiel #5
0
 def __init__(self, config, prefix=None):
     self.manager, self.Manager = None, None
     self.Transport = None
     self.running = False
     self.config = config = Bunch(config)
     
     if prefix is not None:
         self.config = config = Bunch.partial(prefix, config)
     
     try:
         self.manager_config = manager_config = Bunch.partial('manager', config)
     except ValueError:
         self.manager_config = manager_config = Bunch()
     
     try:
         self.transport_config = transport_config = Bunch.partial('transport', config)
     except ValueError:
         self.transport_config = transport_config = Bunch()
     
     try:
         self.message_config = Bunch.partial('message', config)
     except ValueError:
         self.message_config = Bunch()
     
     self.Manager = Manager = self._load(config.manager, 'marrow.mailer.manager')
     
     if not Manager:
         raise LookupError("Unable to determine manager from specification: %r" % (config.manager, ))
     
     self.Transport = Transport = self._load(config.transport, 'marrow.mailer.transport')
     
     if not Transport:
         raise LookupError("Unable to determine transport from specification: %r" % (config.transport, ))
     
     self.manager = Manager(manager_config, partial(Transport, transport_config))
 def __init__(self, config, prefix=None):
     self.manager, self.Manager = None, None
     self.Transport = None
     self.running = False
     self.config = config = Bunch(config)
     
     if prefix is not None:
         self.config = config = Bunch.partial(prefix, config)
     
     try:
         if 'manager' in config and isinstance(config.manager, dict):
             self.manager_config = manager_config = config.manager
         else:
             self.manager_config = manager_config = Bunch.partial('manager', config)
     except ValueError: # pragma: no cover
         self.manager_config = manager_config = Bunch()
     
     if isinstance(config.manager, basestring):
         warnings.warn("Use of the manager directive is deprecated; use manager.use instead.", DeprecationWarning)
         manager_config.use = config.manager
     
     try:
         if 'transport' in config and isinstance(config.transport, dict):
             self.transport_config = transport_config = Bunch(config.transport)
         else:
             self.transport_config = transport_config = Bunch.partial('transport', config)
     except ValueError: # pragma: no cover
         self.transport_config = transport_config = Bunch()
     
     if isinstance(config.transport, basestring):
         warnings.warn("Use of the transport directive is deprecated; use transport.use instead.", DeprecationWarning)
         transport_config.use = config.transport
     
     try:
         if 'message' in config and isinstance(config.message, dict):
             self.message_config = Bunch(config.message)
         else:
             self.message_config = Bunch.partial('message', config)
     except ValueError: # pragma: no cover
         self.message_config = Bunch()
     
     self.Manager = Manager = self._load(manager_config.use if 'use' in manager_config else 'immediate', 'marrow.mailer.manager')
     
     if not Manager:
         raise LookupError("Unable to determine manager from specification: %r" % (config.manager, ))
     
     if not isinstance(Manager, IManager):
         raise TypeError("Chosen manager does not conform to the manager API.")
     
     self.Transport = Transport = self._load(transport_config.use, 'marrow.mailer.transport')
     
     if not Transport:
         raise LookupError("Unable to determine transport from specification: %r" % (config.transport, ))
     
     if not isinstance(Transport, ITransport):
         raise TypeError("Chosen transport does not conform to the transport API.")
     
     self.manager = Manager(manager_config, partial(Transport, transport_config))
Beispiel #7
0
 def test_partial(self):
     d1 = Bunch({'foo.bar': 1, 'foo.baz': 2, 'diz': 3})
     d2 = Bunch.partial('foo', d1)
     
     self.assertEqual(d2.get('diz', None), None)
     self.assertEqual(d2.baz, 2)
     
     d2.bar = 4
     
     self.assertEqual(d1['foo.bar'], 1)
     self.assertEqual(d1.foo.bar, 1)
     
     self.assertRaises(AttributeError, lambda: d1.bar.foo)
Beispiel #8
0
Datei: form.py Projekt: Acen/core
 def native(self, data):
     from marrow.util.bunch import Bunch
     result = dict()
     
     data = data[self.name] if self.name in data else Bunch.partial(self.name, data)
     
     for child in self.children:
         if isinstance(child, NestedWidget):
             result.update(child.native(Bunch.partial(child.name, data))[0])
             continue
         
         result[child.name] = child.native(data)
     
     return {self.name: result}, dict()
Beispiel #9
0
    def native(self, data):
        from marrow.util.bunch import Bunch
        result = dict()

        data = data[self.name] if self.name in data else Bunch.partial(
            self.name, data)

        for child in self.children:
            if isinstance(child, NestedWidget):
                result.update(child.native(Bunch.partial(child.name, data))[0])
                continue

            result[child.name] = child.native(data)

        return {self.name: result}, dict()
Beispiel #10
0
 def post(self, ajax=False, **kw):
     data = Bunch(kw)
     
     data.password = (data.password, data.yubikey)
     
     if 'redirect' not in data:
         data.redirect = '/'
     
     if not web.auth.authenticate(data.identity, data.password):
         web.core.session['flash'] = dict(cls="error", title="Authentication Failure", message="Invalid username or password.")
         return 'login', dict(redirect=data.redirect, identity=data.identity)
     
     web.core.session['flash'] = dict(cls="success", title="Success", message="Successful authentication.")
     
     raise web.core.http.HTTPFound(location=data.redirect)
Beispiel #11
0
    def post(self, **kw):
        data = Bunch(kw)
        
        try:
            data.key = int(data.key)
            if data.key <= KEY_RESET_FLOOR:
                return 'json:', dict(success=False, 
                                     message=_("The key given (%d) must be above minimum reset floor value of %d. Please reset your EVE API Key." % (data.key, KEY_RESET_FLOOR)), 
                                     field='key')
                
        except ValueError:
            return 'json:', dict(success=False, message=_("Key ID must be a number."), field='key')
        
        record = EVECredential(data.key, data.code, owner=user.id)
        
        try:
            record.save()
            #Necessary to guarantee that the pull finished before returning.
            record.pull()
            characters = []
            for character in record.characters:
                characters.append(dict(identifier = character.identifier, name = character.name))
            

            if request.is_xhr:
                return 'json:', dict(
                        success = True,
                        message = _("Successfully added EVE API key."),
                        identifier = str(record.id),
                        key = record.key,
                        code = record.code,
                        characters = characters,
                        violation = record.violation
                    )
        
        except ValidationError:
            if request.is_xhr:
                return 'json:', dict(
                        success = False,
                        message = _("Validation error: one or more fields are incorrect or missing."),
                    )
        except NotUniqueError:
            return 'json:', dict(
                success = False,
                message = _("This key has already been added by another account."),
            )

        raise HTTPFound(location='/key/')
Beispiel #12
0
 def recurse(parts, target, source, indent=0):
     parts = list(parts)
     
     while parts:
         part = parts.pop(0)
         
         if hasattr(part.source, '__call__'):
             part.source = part.source(options)
         
         if hasattr(part.target, '__call__'):
             part.target = part.target(options)
         
         if isinstance(part, (Folder, File)) and not part.condition(options):
             # print("%sSkipping source %s %s..." % ("    " * indent, part.__class__.__name__.lower(), part.source))
             continue
         
         if isinstance(part, Folder):
             print("%sEntering %s..." % ("    " * indent, part.target))
             
             newtarget = path.join(target, part.target) if part.target else target
             if not path.exists(newtarget):
                 os.makedirs(newtarget)
             
             recurse(part.children, newtarget, (source + '/' + part.source) if part.source else source, indent+1)
         
         elif isinstance(part, File):
             print("%sConstructing %s%s..." % ("    " * indent, part.target, (" from %s" % (path.basename(part.source), )) if part.source != part.target else ""))
             # print("%s -> %s" % (source + '/' + part.source, path.join(target, part.target)))
             try:
                 data = Bunch(settings=options)
                 
                 if hasattr(part.data, '__call__'):
                     data.update(part.data(options))
                 else:
                     data.update(part.data)
                 
                 _, content = self.engines(source + '/' + part.source, data)
             
             except:
                 print("\nError constructing %s%s.\n" % (part.target, (" from %s" % (path.basename(part.source), )) if part.source != part.target else ""))
                 raise
             
             with open(path.join(target, part.target), 'w') as fh:
                 fh.write(content)
         
         elif hasattr(part, '__call__'):
             additional = part(self.options)
             parts.extend(additional)
Beispiel #13
0
 def __call__(self, *credential, **payload):
     """Perform the RPC call while following CCP's caching guidelines."""
     
     if len(credential) > 1:
         raise Exception("The only positional parameter allowed is the credentials object.")
     
     now = datetime.utcnow()
     uri = self.uri(self.name)
     
     # Define the keyID/vCode API key arguments, if we have credentials.
     if credential:
         payload['keyID'] = credential[0].key
         payload['vCode'] = credential[0].code
     
     # Hash the arguments in a reliable way by converting to text in a way which sorts the keys.
     payload_hash = sha256(EnhancedBencode().encode(payload)).hexdigest()
     
     # Examine the cache.
     cv = CachedAPIValue.objects(
             key = payload.get('keyID', None),
             name = self.name,
             arguments = payload_hash,
             expires__gte = now
         ).first()
     
     if cv and cv.current:
         log.info("Returning cached result of %s for key ID %d.", self.name, payload.get('keyID', -1))
         return bunchify_lite(cv.result)
     
     log.info("Making query to %s for key ID %d.", self.name, payload.get('keyID', -1))
     
     # Actually perform the query if a cached version could not be found.
     response = requests.post(uri, data=payload or None)
     response.raise_for_status()
     
     # We don't want the initial XML prefix.  We should still check it, though.
     prefix, _, data = response.text.partition('\n')
     
     if prefix.strip() != "<?xml version='1.0' encoding='UTF-8'?>":
         raise Exception("Data returned doesn't seem to be XML!")
     
     data = xml(data)['eveapi']
     result = bunchify(data['result'], 'result')
     data = Bunch(data)
     
     if len(result) == 1:
         result = getattr(result, result.keys()[0])
     
     # Upsert (update if exists, create if it doesn't) the cache value.
     CachedAPIValue.objects(
             key = payload.get('keyID', None),
             name = self.name,
             arguments = payload_hash
         ).update_one(
             upsert = True,
             set__expires = datetime.strptime(data.cachedUntil, "%Y-%m-%d %H:%M:%S"),
             set__result = result
         )
     
     return result
Beispiel #14
0
    def __post_email(self, **post):
        try:
            data = Bunch(recover_form.native(post)[0])
        except Exception as e:
            if config.get('debug', False):
                raise
            return 'json:', dict(success=False,
                                 message=_("Unable to parse data."),
                                 data=post,
                                 exc=str(e))

        user = lookup_email(data.email)
        if not user:
            user = lookup_email(data.email.lower())
        if not user:
            # FixMe: possibly do send success any way, to prevent email address confirmation
            #   - would be necessary for register as well
            return 'json:', dict(success=False,
                                 message=_("Unknown email."),
                                 data=post)
        send_recover_email(user)
        return 'json:', dict(
            success=True,
            message=_(
                "Recovery e-mail sent - "
                "please follow the instructions in that mail to restore your password"
            ))
Beispiel #15
0
        def inner(cls, search):
            record = cls.get(search)
            if not record:
                return dict(success=False, message="No matching record found.")

            result = Bunch(success=True)

            def process(value):
                if isinstance(value, EVEEntity):
                    if cls is EVEAlliance and isinstance(
                            value, EVECorporation):
                        return dict(id=value.identifier,
                                    name=value.name,
                                    joined=process(value.joined))
                    return dict(id=value.identifier, name=value.name)
                if hasattr(value, 'strftime'):
                    return value.strftime('%y-%m-%d %H:%M:%S')
                if isinstance(value, list) or hasattr(value, '__iter__'):
                    return [process(i) for i in value]
                return value

            for field in fields:
                result[_mapping.get(field,
                                    field)] = process(getattr(record, field))

            return result
Beispiel #16
0
def bunchify(data, name=None):
    if isinstance(data, Bunch):
        return data
    
    if isinstance(data, list):
        if name == 'rowset':  # we unpack these into a dictionary based on name
            return Bunch({i['name']: bunchify(i, 'rowset') for i in data})
        
        return [bunchify(i) for i in data]
    
    if isinstance(data, dict):
        data = data.copy()
        
        if name == 'row' and 'row' in data:
            # Special case of CCP's silly key:value text.
            pass
        
        if name and name in data and not data.get(name, '').strip():
            data.pop(name)
        
        if name == 'rowset' and 'name' in data:
            data.pop('name')
        
        if len(data) == 1 and isinstance(data.values()[0], dict):
            return bunchify(data.values()[0], data.keys()[0])
        
        result = Bunch({
                k: bunchify(
                        [v] if k in ('row', ) and not isinstance(v, list) else v,
                        k
                    ) for k, v in data.iteritems() if k != 'rowset'
            })
        
        if 'rowset' in data:
            rowset = bunchify(data['rowset'] if isinstance(data['rowset'], list) else [data['rowset']], 'rowset')
            result.update(rowset)
        
        if name == 'rowset':  # rowsets always contain rows, even if there are no results
            result.setdefault('row', [])
        
        return result
    
    if isinstance(data, str):
        data = data.decode('utf-8')
    
    if isinstance(data, (str, unicode)):
        try:
            return number(data)
        except ValueError:
            pass
        
        try:
            return boolean(data)
        except ValueError:
            pass
        
        if ',' in data and (name in ('key', 'columns') or ' ' not in data):
            return array(data)
    
    return data
Beispiel #17
0
    def post(self, **post):
        try:
            data = Bunch(register_form.native(post)[0])
        except Exception as e:
            if config.get('debug', False):
                raise
            return 'json:', dict(success=False,
                                 message=_("Unable to parse data."),
                                 data=post,
                                 exc=str(e))

        if not data.username or not data.email or not data.password or data.password != data.pass2:
            return 'json:', dict(
                success=False,
                message=_("Missing data or passwords do not match."),
                data=data)

        #Make sure that the provided email address is a valid form for an email address
        v = EmailValidator()
        email = data.email
        email, err = v.validate(email)
        if err:
            return 'json:', dict(success=False,
                                 message=_("Invalid email address provided."),
                                 data=data)

        #If the password isn't strong enough, reject it
        if (zxcvbn.password_strength(data.password).get("score") <
                MINIMUM_PASSWORD_STRENGTH):
            return 'json:', dict(
                success=False,
                message=
                _("Password provided is too weak. please add more characters, or include lowercase, uppercase, and special characters."
                  ),
                data=data)

        #Ensures that the provided username and email are lowercase
        user = User(data.username.lower(), data.email.lower(), active=True)
        user.password = data.password
        try:
            user.save()
        except ValidationError:
            return 'json:', dict(success=False,
                                 message=_("Invalid email address provided."),
                                 data=data)
        except NotUniqueError:
            return 'json:', dict(
                success=False,
                message=
                _("Either the username or email address provided is already taken."
                  ),
                data=data)

        authenticate(user.username, data.password)

        return 'json:', dict(success=True, location="/")
Beispiel #18
0
 def test_delete(self):
     d = Bunch(name='value')
     del d.name
     
     self.assertEqual(repr(d), 'Bunch({})')
     
     def error_test():
         del d.foo
     
     self.assertRaises(AttributeError, error_test)
Beispiel #19
0
    def __call__(self, *args, **kwargs):
        result = self.pool.post(
            self.path + (('/' + '/'.join(args)) if args else ''),
            data=kwargs,
            auth=SignedAuth(self.identity, self.private, self.public))

        if not result.status_code == requests.codes.ok:
            return None

        return Bunch(result.json())
Beispiel #20
0
    def __init__(self, application, config=dict(), prefix='auth.'):
        self.application = application

        prefix_length = len(prefix)
        our_config = Bunch(default_config.copy())

        for i, j in config.iteritems():
            if i.startswith(prefix):
                our_config[i[prefix_length:]] = j

        our_config.intercept = [i.strip() for i in array(our_config.intercept)]
        our_config.internal = boolean(our_config.internal)

        if our_config.lookup is None:
            raise Exception('You must define an authentication lookup method.')

        our_config.lookup = self.get_method(our_config.lookup)
        our_config.authenticate = self.get_method(our_config.authenticate)

        web.auth.config = our_config
Beispiel #21
0
 def specification(self):
     """Determine the high-level script specification.
     
     Additionally, prepare the way for sub-command calling.
     """
     
     spec = Bunch(
             name = None,
             author = None,
             version = None,
             copyright = None,
             license = None,
             url = None
         )
     
     # TODO: Load some of this from setuptools.
     spec.update(getattr(self.callable, '_cmd_script_info', dict()))
     
     spec.callables = [
             self.specification_for(self.callable, spec)
         ]
     
     return spec
Beispiel #22
0
def bunchify(data, name=None):
    if isinstance(data, Bunch):
        return data

    if isinstance(data, list):
        return [bunchify(i) for i in data]

    if isinstance(data, dict):
        if hasattr(data, 'iteritems'):
            bunch_data = {k: bunchify(v, k) for k, v in data.iteritems()}
        else:
            bunch_data = {k: bunchify(v, k) for k, v in data.items()}
        return Bunch(bunch_data)

    return data
Beispiel #23
0
    def get(self, call, **kwargs):
        from newauth.models import APIKey, db
        cache_key = hash((self.base, call, frozenset(kwargs)))
        cached_data = redis.get(cache_key)
        if cached_data:
            cached_data = cPickle.loads(cached_data)
            if arrow.utcnow() < cached_data[0]:
                return cached_data[1]
        try:
            req = self.session.get(self.base + call + '.xml.aspx',
                                   params=kwargs)
            req.raise_for_status()
        except requests.exceptions.RequestException as e:
            raise e
        if req.status_code != 200:
            if req.status_code == requests.codes['not_found']:
                raise Exception(
                    "{} is not available on the API server (404)".format(
                        call.value))
            elif req.status_code == requests.codes['forbidden']:
                if self.api_key and self.api_key.id:
                    self.api_key.disabled = True
                    db.session.add(self.api_key)
                    db.session.commit()
                raise AuthenticationException(self.key_id)
            else:
                raise Exception("Eve API server exception.")
        request_data = req.text

        prefix, _, data = req.text.partition('\n')
        if prefix.strip() != "<?xml version='1.0' encoding='UTF-8'?>":
            raise Exception("Data returned doesn't seem to be XML!")

        if isinstance(data, unicode):
            data = data.encode('UTF-8')

        data = xml(data)['eveapi']
        result = bunchify(data['result'], 'result')
        data = Bunch(data)

        if len(result) == 1:
            result = getattr(result, result.keys())[0]
        redis.set(cache_key,
                  cPickle.dumps((arrow.get(data.cachedUntil), result), -1))
        return result
Beispiel #24
0
 def post(self, **post):
     try:
         data = Bunch(register_form.native(post)[0])
     except Exception as e:
         if config.get('debug', False):
             raise
         return 'json:', dict(success=False, message="Unable to parse data.", data=post, exc=str(e))
     
     if not data.username or not data.email or not data.password or data.password != data.pass2:
         return 'json:', dict(success=False, message="Missing data?", data=data)
     
     user = User(data.username, data.email, active=True)
     user.password = data.password
     user.save()
     
     authenticate(data.username, data.password)
     
     return 'json:', dict(success=True, location="/")
Beispiel #25
0
    def post(self, **kw):
        data = Bunch(kw)

        record = EVECredential(data.key, data.code, owner=user.id)
        record.save()

        # If record is a character key:
        #   Create character owned by user.id

        if request.is_xhr:
            return 'json:', {
                'success': True,
                'identifier': str(record.id),
                'key': record.key,
                'code': record.code
            }

        raise HTTPFound(location='/key/')
Beispiel #26
0
    def __post_recovery(self, **post):
        try:
            data = Bunch(reset_password_form.native(post)[0])
        except Exception as e:
            if config.get('debug', False):
                raise
            return 'json:', dict(success=False,
                                 message=_("Unable to parse data."),
                                 data=post,
                                 exc=str(e))
        recovery = self.__get_recovery(data.email, data.recovery_key)
        if not recovery:
            return 'json:', dict(
                success=False,
                message=_("Sorry that recovery link has already expired"),
                location="/account/recover")
        passwd_ok, error_msg = _check_password(data.password, data.pass2)
        if not passwd_ok:
            return 'json:', dict(success=False, message=error_msg)

        #If the password isn't strong enough, reject it
        if (zxcvbn.password_strength(data.password).get("score") <
                MINIMUM_PASSWORD_STRENGTH):
            return 'json:', dict(
                success=False,
                message=
                _("Password provided is too weak. please add more characters, or include lowercase, uppercase, and special characters."
                  ),
                data=data)

        #set new password
        user = recovery.user
        user.password = data.password
        user.save()

        #remove recovery key
        recovery.delete()

        authenticate(user.username, data.password)

        return 'json:', dict(success=True,
                             message=_("Password changed, forwarding ..."),
                             location="/")
Beispiel #27
0
    def get(self, redirect=None, **get):
        if redirect is None:
            referrer = request.referrer
            redirect = '/' if not referrer or referrer.endswith(
                request.script_name) else referrer
        try:
            data = Bunch(reset_password_form.native(get)[0])
        except Exception as e:
            if config.get('debug', False):
                raise
            raise HTTPFound(
                location='/')  # Todo redirect to recover with error message

        if not data.recovery_key:  # no key passed, so show email entry
            form = recover_form(dict(redirect=redirect))
            button_label = _("Recover")
        else:
            form = reset_password_form(
                dict(email=data.email, recovery_key=data.recovery_key))
            button_label = _("Set Password")

        return "brave.core.account.template.recover", dict(
            form=form, button_label=str(button_label))
Beispiel #28
0
    def post(self, **kw):
        data = Bunch(kw)

        record = EVECredential(data.key, data.code, owner=user.id)
        try:
            record.save()
            record.importChars()
            if request.is_xhr:
                return 'json:', {
                    'success': True,
                    'identifier': str(record.id),
                    'key': record.key,
                    'code': record.code
                }
        except ValidationError:
            if request.is_xhr:
                return 'json:', {
                    'success':
                    False,
                    'message':
                    'Validation error for Eve Credential: One or more fields are incorrect or missing'
                }

        raise HTTPFound(location='/key/')
Beispiel #29
0
 def test_empty_creation(self):
     d = Bunch()
     assert not d
Beispiel #30
0
 def test_attribute_read(self):
     d = Bunch()
     d.name = 'value'
     assert d.name == 'value'
Beispiel #31
0
 def test_repr(self):
     d = Bunch()
     assert repr(d) == 'Bunch({})'
     
     d.name = 'value'
     self.assertEqual(repr(d), "Bunch({'name': 'value'})")
Beispiel #32
0
# encoding: utf-8

from unittest import TestCase

from marrow.util.bunch import Bunch
from marrow.util.escape import unescape

PLAYERS = Bunch(alice=Bunch(name="Alice", gender='female'),
                bob=Bunch(name="Bob", gender='male'),
                everyone=Bunch(name="everyone", gender='group'),
                bender=Bunch(name='Bender', gender='i', role="bending robot"))

CASES = [
    (None, '%N', 'Anonymous'),
    (PLAYERS.alice, '%N welcomes you.', 'Alice welcomes you.'),
    (PLAYERS.alice, 'The book is %a.', 'The book is hers.'),
    (PLAYERS.alice, '%S loves coffee.', 'She loves coffee.'),
    (PLAYERS.alice, '%s %o %p %a %S %O %P %A %N',
     'she her her hers She Her Her Hers Alice'),
    (PLAYERS.bob, '%s %o %p %a %S %O %P %A %N',
     'he him his his He Him His His Bob'),
    (PLAYERS.everyone, '%s %o %p %a %S %O %P %A %N',
     'they them their theirs They Them Their Theirs everyone'),
    (PLAYERS.bender, '%s %o %p %a %S %O %P %A %N',
     'it it its its It It Its Its Bender'),
]


def assert_expected(caller, testing, expected, obj=None):
    assert unescape(caller, testing,
                    obj) == expected, "Expected '%s', returned '%s'." % (
Beispiel #33
0
 def test_attribute_assignment(self):
     d = Bunch()
     d.name = 'value'
     assert hasattr(d, 'name')
     self.assertEqual(d['name'], 'value')
Beispiel #34
0
    def post(self, **post):
        try:
            data = Bunch(post)
        except Exception as e:
            if config.get('debug', False):
                raise
            return 'json:', dict(success=False,
                                 message=_("Unable to parse data."),
                                 data=post,
                                 exc=str(e))

        query = dict(active=True)
        query[b'username'] = data.id

        user = User.objects(**query).first()

        if data.form == "changepassword":
            passwd_ok, error_msg = _check_password(data.passwd, data.passwd1)

            if not passwd_ok:
                return 'json:', dict(success=False,
                                     message=error_msg,
                                     data=data)

            if isinstance(data.old, unicode):
                data.old = data.old.encode('utf-8')

            if not User.password.check(user.password, data.old):
                return 'json:', dict(success=False,
                                     message=_("Old password incorrect."),
                                     data=data)

            #If the password isn't strong enough, reject it
            if (zxcvbn.password_strength(data.passwd).get("score") <
                    MINIMUM_PASSWORD_STRENGTH):
                return 'json:', dict(
                    success=False,
                    message=
                    _("Password provided is too weak. please add more characters, or include lowercase, uppercase, and special characters."
                      ),
                    data=data)

            user.password = data.passwd
            user.save()
        elif data.form == "addotp":
            if isinstance(data.password, unicode):
                data.password = data.password.encode('utf-8')

            identifier = data.otp
            client = yubico.Yubico(config['yubico.client'],
                                   config['yubico.key'],
                                   boolean(config.get('yubico.secure', False)))

            if not User.password.check(user.password, data.password):
                return 'json:', dict(success=False,
                                     message=_("Password incorrect."),
                                     data=data)

            try:
                status = client.verify(identifier, return_response=True)
            except:
                return 'json:', dict(success=False,
                                     message=_("Failed to contact YubiCloud."),
                                     data=data)

            if not status:
                return 'json:', dict(success=False,
                                     message=_("Failed to verify key."),
                                     data=data)

            if not User.addOTP(user, identifier[:12]):
                return 'json:', dict(success=False,
                                     message=_("YubiKey already exists."),
                                     data=data)
        elif data.form == "removeotp":
            identifier = data.otp

            if not User.removeOTP(user, identifier[:12]):
                return 'json:', dict(success=False,
                                     message=_("YubiKey invalid."),
                                     data=data)

        elif data.form == "configureotp":
            if isinstance(data.password, unicode):
                data.password = data.password.encode('utf-8')
            rotp = True if 'rotp' in data else False

            if not User.password.check(user.password, data.password):
                return 'json:', dict(success=False,
                                     message=_("Password incorrect."),
                                     data=data)

            user.rotp = rotp
            user.save()

        #Handle the user attempting to delete their account
        elif data.form == "deleteaccount":
            if isinstance(data.passwd, unicode):
                data.passwd = data.passwd.encode('utf-8')

            #Make the user enter their username so they know what they're doing.
            if not user.username == data.username.lower():
                return 'json:', dict(success=False,
                                     message=_("Username incorrect."),
                                     data=data)

            #Check whether the user's supplied password is correct
            if not User.password.check(user.password, data.passwd):
                return 'json:', dict(success=False,
                                     message=_("Password incorrect."),
                                     data=data)

            #Make them type "delete" exactly
            if not data.confirm == "delete":
                return 'json:', dict(
                    success=False,
                    message=_(
                        "Delete was either misspelled or not lowercase."),
                    data=data)

            #Delete the user account and then deauthenticate the browser session
            log.info("User %s authorized the deletion of their account.", user)
            user.delete()
            deauthenticate()

            #Redirect user to the root of the server instead of the settings page
            return 'json:', dict(success=True, location="/")

        #Handle the user attempting to change the email address associated with their account
        elif data.form == "changeemail":
            if isinstance(data.passwd, unicode):
                data.passwd = data.passwd.encode('utf-8')

            #Check whether the user's supplied password is correct
            if not User.password.check(user.password, data.passwd):
                return 'json:', dict(success=False,
                                     message=_("Password incorrect."),
                                     data=data)

            #Check that the two provided email addresses match
            if not data.newEmail.lower() == data.newEmailConfirm.lower():
                return 'json:', dict(
                    success=False,
                    message=_("Provided email addresses do not match."),
                    data=data)

            #Make sure that the provided email address is a valid form for an email address
            v = EmailValidator()
            email = data.newEmail
            email, err = v.validate(email)
            if err:
                return 'json:', dict(
                    success=False,
                    message=_("Invalid email address provided."),
                    data=data)

            #Make sure that the new email address is not already taken
            count = User.objects.filter(**{
                "email": data.newEmail.lower()
            }).count()
            if not count == 0:
                return 'json:', dict(
                    success=False,
                    message=_("The email address provided is already taken."),
                    data=data)

            #Change the email address in the database and catch any email validation exceptions that mongo throws
            user.email = data.newEmail.lower()
            try:
                user.save()
            except ValidationError:
                return 'json:', dict(
                    success=False,
                    message=_("Invalid email address provided."),
                    data=data)
            except NotUniqueError:
                return 'json:', dict(
                    success=False,
                    message=_("The email address provided is already taken."),
                    data=data)

        #Handle the user attempting to merge 2 accounts together
        elif data.form == "mergeaccount":
            if isinstance(data.passwd, unicode):
                data.passwd = data.passwd.encode('utf-8')

            if isinstance(data.passwd2, unicode):
                data.passwd2 = data.passwd2.encode('utf-8')

            #Make the user enter their username so they know what they're doing.
            if user.username != data.username.lower(
            ) and user.username != data.username:
                return 'json:', dict(success=False,
                                     message=_("First username incorrect."),
                                     data=data)

            #Check whether the user's supplied password is correct
            if not User.password.check(user.password, data.passwd):
                return 'json:', dict(success=False,
                                     message=_("First password incorrect."),
                                     data=data)

            #Make sure the user isn't trying to merge their account into itself.
            if data.username.lower() == data.username2.lower():
                return 'json:', dict(
                    success=False,
                    message=_("You can't merge an account into itself."),
                    data=data)

            #Make the user enter the second username so we can get the User object they want merged in.
            if not User.objects(
                    username=data.username2.lower()) and not User.objects(
                        username=data.username2):
                return 'json:', dict(
                    success=False,
                    message=_("Unable to find user by second username."),
                    data=data)

            other = User.objects(username=data.username2).first()
            if not other:
                other = User.objects(username=data.username2.lower()).first()

            #Check whether the user's supplied password is correct
            if not User.password.check(other.password, data.passwd2):
                return 'json:', dict(success=False,
                                     message=_("Second password incorrect."),
                                     data=data)

            #Make them type "merge" exactly
            if data.confirm != "merge":
                return 'json:', dict(
                    success=False,
                    message=_("Merge was either misspelled or not lowercase."),
                    data=data)

            log.info("User %s merged account %s into %s.", user.username,
                     other.username, user.username)
            user.merge(other)

            #Redirect user to the root of the server instead of the settings page
            return 'json:', dict(success=True, location="/")

        else:
            return 'json:', dict(success=False,
                                 message=_("Form does not exist."),
                                 location="/")

        return 'json:', dict(success=True, location="/account/settings")
Beispiel #35
0
    def post(self, **post):
        try:
            data = Bunch(post)
        except Exception as e:
            if config.get('debug', False):
                raise
            return 'json:', dict(success=False, message=_("Unable to parse data."), data=post, exc=str(e))

        query = dict(active=True)
        query[b'username'] = data.id

        query_user = User.objects(**query).first()
        if query_user.id != user.id:
            raise HTTPForbidden

        if data.form == "changepassword":
            passwd_ok, error_msg = _check_password(data.passwd, data.passwd1)

            if not passwd_ok:
                return 'json:', dict(success=False, message=error_msg, data=data)

            if isinstance(data.old, unicode):
                data.old = data.old.encode('utf-8')

            if not User.password.check(user.password, data.old):
                return 'json:', dict(success=False, message=_("Old password incorrect."), data=data)

            #If the password isn't strong enough, reject it
            if(zxcvbn.password_strength(data.passwd).get("score") < MINIMUM_PASSWORD_STRENGTH):
                return 'json:', dict(success=False, message=_("Password provided is too weak. please add more characters, or include lowercase, uppercase, and special characters."), data=data)

            user.password = data.passwd
            user.save()
        elif data.form == "addotp":
            if isinstance(data.password, unicode):
                data.password = data.password.encode('utf-8')

            identifier = data.otp
            client = yubico.Yubico(
                config['yubico.client'],
                config['yubico.key'],
                boolean(config.get('yubico.secure', False))
            )

            if not User.password.check(user.password, data.password):
                return 'json:', dict(success=False, message=_("Password incorrect."), data=data)

            try:
                status = client.verify(identifier, return_response=True)
            except:
                return 'json:', dict(success=False, message=_("Failed to contact YubiCloud."), data=data)

            if not status:
                return 'json:', dict(success=False, message=_("Failed to verify key."), data=data)

            if not User.addOTP(user, identifier[:12]):
                return 'json:', dict(success=False, message=_("YubiKey already exists."), data=data)
        elif data.form == "removeotp":
            identifier = data.otp

            if not User.removeOTP(user, identifier[:12]):
                return 'json:', dict(success=False, message=_("YubiKey invalid."), data=data)

        elif data.form == "configureotp":
            if isinstance(data.password, unicode):
                data.password = data.password.encode('utf-8')
            rotp = True if 'rotp' in data else False

            if not User.password.check(user.password, data.password):
                return 'json:', dict(success=False, message=_("Password incorrect."), data=data)
            
            user.rotp = rotp
            user.save()
            
        #Handle the user attempting to delete their account
        elif data.form == "deleteaccount":
            if isinstance(data.passwd, unicode):
                data.passwd = data.passwd.encode('utf-8')
             
            #Make the user enter their username so they know what they're doing.
            if not user.username == data.username.lower():
                return 'json:', dict(success=False, message=_("Username incorrect."), data=data)
        
            #Check whether the user's supplied password is correct
            if not User.password.check(user.password, data.passwd):
                return 'json:', dict(success=False, message=_("Password incorrect."), data=data)
                
            #Make them type "delete" exactly
            if not data.confirm == "delete":
                return 'json:', dict(success=False, message=_("Delete was either misspelled or not lowercase."), data=data)
            
            #Delete the user account and then deauthenticate the browser session
            log.info("User %s authorized the deletion of their account.", user)
            user.delete()
            deauthenticate()
            
            #Redirect user to the root of the server instead of the settings page
            return 'json:', dict(success=True, location="/")
            
        #Handle the user attempting to change the email address associated with their account
        elif data.form == "changeemail":
            if isinstance(data.passwd, unicode):
                data.passwd = data.passwd.encode('utf-8')
        
            #Check whether the user's supplied password is correct
            if not User.password.check(user.password, data.passwd):
                return 'json:', dict(success=False, message=_("Password incorrect."), data=data)

            #Check that the two provided email addresses match
            if not data.newEmail.lower() == data.newEmailConfirm.lower():
                return 'json:', dict(success=False, message=_("Provided email addresses do not match."), data=data)
            
            #Make sure that the provided email address is a valid form for an email address
            v = EmailValidator()
            email = data.newEmail
            email, err = v.validate(email)
            if err:
                return 'json:', dict(success=False, message=_("Invalid email address provided."), data=data)
                
            #Make sure that the new email address is not already taken
            count = User.objects.filter(**{"email": data.newEmail.lower()}).count()
            if not count == 0:
                return 'json:', dict(success=False, message=_("The email address provided is already taken."), data=data)
       
            #Change the email address in the database and catch any email validation exceptions that mongo throws
            user.email = data.newEmail.lower()
            try:
                user.save()
            except ValidationError:
                return 'json:', dict(success=False, message=_("Invalid email address provided."), data=data)
            except NotUniqueError:
                return 'json:', dict(success=False, message=_("The email address provided is already taken."), data=data)
        
        #Handle the user attempting to merge 2 accounts together
        elif data.form == "mergeaccount":
            if isinstance(data.passwd, unicode):
                data.passwd = data.passwd.encode('utf-8')
                
            if isinstance(data.passwd2, unicode):
                data.passwd2 = data.passwd2.encode('utf-8')
                
            #Make the user enter their username so they know what they're doing.
            if user.username != data.username.lower() and user.username != data.username:
                return 'json:', dict(success=False, message=_("First username incorrect."), data=data)
                
            #Check whether the user's supplied password is correct
            if not User.password.check(user.password, data.passwd):
                return 'json:', dict(success=False, message=_("First password incorrect."), data=data)
                
            #Make sure the user isn't trying to merge their account into itself.
            if data.username.lower() == data.username2.lower():
                return 'json:', dict(success=False, message=_("You can't merge an account into itself."), data=data)
                
            #Make the user enter the second username so we can get the User object they want merged in.
            if not User.objects(username=data.username2.lower()) and not User.objects(username=data.username2):
                return 'json:', dict(success=False, message=_("Unable to find user by second username."), data=data)
                
            other = User.objects(username=data.username2).first()
            if not other:
                other = User.objects(username=data.username2.lower()).first()
                
            #Check whether the user's supplied password is correct
            if not User.password.check(other.password, data.passwd2):
                return 'json:', dict(success=False, message=_("Second password incorrect."), data=data)
                
            #Make them type "merge" exactly
            if data.confirm != "merge":
                return 'json:', dict(success=False, message=_("Merge was either misspelled or not lowercase."), data=data)
                
            log.info("User %s merged account %s into %s.", user.username, other.username, user.username)
            user.merge(other)
            
            #Redirect user to the root of the server instead of the settings page
            return 'json:', dict(success=True, location="/")
            
        else:
            return 'json:', dict(success=False, message=_("Form does not exist."), location="/")
        
        return 'json:', dict(success=True, location="/account/settings")
Beispiel #36
0
import pkg_resources

from marrow.util.bunch import Bunch

# from web.extras.cmf.core.decorators import action, view



__all__ = ['components', 'action', 'api', 'view', 'Action', 'View']
log = __import__('logging').getLogger(__name__)



connection = None
components = Bunch()
models = Bunch()
namespace = Bunch()


# namespace.master = [dotted.get_dotted_filename(config.master)] if config.get('master', None) else []

for res in pkg_resources.iter_entry_points('contentment.component'):
    try:
        instance = res.load()
        
        if callable(instance):
            instance = instance()
    
    except:
        log.exception("Error scanning available CMF components.  CMF unavailable.")
        break
Beispiel #37
0
			
			yield last.split('/'), parent, False
			
			last = str(chunk)
		
		if isclass(current):
			current = current(context)
		
		yield last.split('/'), current, True


if __debug__ and __name__ == '__main__':  # pragma: no cover
	from marrow.util.bunch import Bunch
	from marrow.logging import Log, DEBUG
	
	request = Bunch(remainder='/')
	context = Bunch(log=Log(level=DEBUG).name(__file__), request=request)
	
	class Controller(object):
		def __init__(self, context):
			self._ctx = context
	
	class RootController(Controller):
		def __call__(self):
			return "Hello world!"
	
	router = ObjectDispatchDialect(dict())
	
	for i,j,k in router(context, RootController):
		context.log.info(path=i,obj=j,final=k)
	
Beispiel #38
0
    def post(self, **kw):
        data = Bunch(kw)

        try:
            data.key = int(data.key)
            if data.key <= int(config["core.minimum_key_id"]):
                return (
                    "json:",
                    dict(
                        success=False,
                        message=_(
                            "The key given (%d) must be above minimum reset floor value of %d. "
                            "Please reset your EVE API Key." % (data.key, int(config["core.minimum_key_id"]))
                        ),
                        field="key",
                    ),
                )

        except ValueError:
            return "json:", dict(success=False, message=_("Key ID must be a number."), field="key")

        record = EVECredential(data.key, data.code, owner=user.id)

        try:
            record.save()
            # Necessary to guarantee that the pull finished before returning.
            record.pull()
            characters = []
            for character in record.characters:
                characters.append(dict(identifier=character.identifier, name=character.name))

            if request.is_xhr:
                return (
                    "json:",
                    dict(
                        success=True,
                        message=_("Successfully added EVE API key."),
                        identifier=str(record.id),
                        key=record.key,
                        code=record.code,
                        characters=characters,
                        violation=record.violation,
                    ),
                )

        except ValidationError:
            if request.is_xhr:
                return (
                    "json:",
                    dict(success=False, message=_("Validation error: one or more fields are incorrect or missing.")),
                )
        except NotUniqueError:
            if EVECredential.objects(key=data.key):
                # Mark both of these accounts as duplicates to each other.
                acc = User.objects(username=user.username).first()
                other = EVECredential.objects(key=data.key).first().owner

                User.add_duplicate(acc, other)

            return (
                "json:",
                dict(success=False, message=_("This key has already been added to this or another account.")),
            )

        raise HTTPFound(location="/key/")
Beispiel #39
0
    def __init__(self, config, prefix=None):
        self.manager, self.Manager = None, None
        self.Transport = None
        self.running = False
        self.config = config = Bunch(config)

        if prefix is not None:
            self.config = config = Bunch.partial(prefix, config)

        try:
            if 'manager' in config and isinstance(config.manager, dict):
                self.manager_config = manager_config = config.manager
            else:
                self.manager_config = manager_config = Bunch.partial(
                    'manager', config)
        except ValueError:  # pragma: no cover
            self.manager_config = manager_config = Bunch()

        if isinstance(config.manager, basestring):
            warnings.warn(
                "Use of the manager directive is deprecated; use manager.use instead.",
                DeprecationWarning)
            manager_config.use = config.manager

        try:
            if 'transport' in config and isinstance(config.transport, dict):
                self.transport_config = transport_config = Bunch(
                    config.transport)
            else:
                self.transport_config = transport_config = Bunch.partial(
                    'transport', config)
        except ValueError:  # pragma: no cover
            self.transport_config = transport_config = Bunch()

        if isinstance(config.transport, basestring):
            warnings.warn(
                "Use of the transport directive is deprecated; use transport.use instead.",
                DeprecationWarning)
            transport_config.use = config.transport

        try:
            if 'message' in config and isinstance(config.message, dict):
                self.message_config = Bunch(config.message)
            else:
                self.message_config = Bunch.partial('message', config)
        except ValueError:  # pragma: no cover
            self.message_config = Bunch()

        self.Manager = Manager = self._load(
            manager_config.use if 'use' in manager_config else 'immediate',
            'marrow.mailer.manager')

        if not Manager:
            raise LookupError(
                "Unable to determine manager from specification: %r" %
                (config.manager, ))

        if not isinstance(Manager, IManager):
            raise TypeError(
                "Chosen manager does not conform to the manager API.")

        self.Transport = Transport = self._load(transport_config.use,
                                                'marrow.mailer.transport')

        if not Transport:
            raise LookupError(
                "Unable to determine transport from specification: %r" %
                (config.transport, ))

        if not isinstance(Transport, ITransport):
            raise TypeError(
                "Chosen transport does not conform to the transport API.")

        self.manager = Manager(manager_config,
                               partial(Transport, transport_config))
Beispiel #40
0
# encoding: utf-8

import pkg_resources

from web.extras.contentment import release
from web.extras.contentment.api import IComponent

from marrow.util.bunch import Bunch


__all__ = ['PageComponent', 'controller', 'model', 'templates', 'engines']
log = __import__('logging').getLogger(__name__)

engines = Bunch()


class PageComponent(IComponent):
    title = "Page"
    summary = "An embeddable page of static content."
    description = None
    icon = 'base-page'
    group = "Basic Types"
    
    version = release.version
    author = release.author
    email = release.email
    url = release.url
    copyright = release.copyright
    license = release.license
    
    @property
Beispiel #41
0
 def __init__(self):
     """Perform some startup work, like configuring the mail interface."""
     super(RootController, self).__init__()
     
     adam.auth.util.mail = Mailer(Bunch(config).mail)
     adam.auth.util.mail.start()
Beispiel #42
0
 def test_populated_creation(self):
     d = Bunch(name='value')
     self.assertEqual(d['name'], 'value')
     
     d = Bunch({'name': 'value'})
     self.assertEqual(d['name'], 'value')
Beispiel #43
0
 def construct_yaml_bunch(self, node):
     data = Bunch()
     yield data
     value = self.construct_mapping(node)
     data.update(value)
Beispiel #44
0
 def test_death(self):
     transport = MockTransport(dict())
     self.assertRaises(ZeroDivisionError, transport.deliver, Bunch(die=True))