Exemple #1
0
 def extract_email(self, id=None, doc=None):
     doc = doc or self.collection.read(id)
     email = doc.data.get(self.email_field, 'null')
     if re.match(EMAIL_RE, email) is None:
         raise exceptions.BadRequest(
             detail='"{}" at "{}" is not a valid email'.format(
                 email, self.email_field))
     return email
Exemple #2
0
    async def _authenticate(self, data):
        namespace = manager.get_namespace(data['namespace'])
        collection = namespace.get_collection(data['collection'])

        # TODO handle exceptions
        if not (collection.schema
                and 'password' in collection.schema._schema['required']
                and collection.schema._schema['properties']['password']
                == self.PASSWORD_SCHEMA):
            raise exceptions.BadRequest()  # TODO Better error message

        # TODO validate retrieved document
        doc = collection.read(data['username'])
        password = doc.data['password'].encode()

        hashed = await asyncio.get_event_loop().run_in_executor(
            None, lambda: bcrypt.hashpw(data['password'].encode(), password))

        if hashed == password:
            return SelfAuthProvider.type, '{}:{}'.format(
                namespace.name, data['collection']), data['username']
        raise exceptions.Unauthorized()
Exemple #3
0
    async def post(self):
        try:
            data = self.json['data']
        except (TypeError, ValueError, KeyError):
            raise exceptions.MalformedData()

        if data.get('type') != 'users':
            raise exceptions.IncorrectParameter('data.type', 'users',
                                                data.get('type', 'null'))

        if not isinstance(data.get('attributes'), dict):
            raise exceptions.InvalidType('data.attributes', 'dict',
                                         type(data.get('type')))

        try:
            provider = driver.DriverManager(
                namespace='jam.auth.providers',
                name=data['attributes'].pop('provider'),
                invoke_on_load=True,
            ).driver
        except (KeyError, driver.NoMatches):
            raise exceptions.BadRequest(detail='Unknown provider')

        user = await provider.authenticate(self.current_user,
                                           data['attributes'])

        self.write({
            'data': {
                'id': user.uid,
                'type': 'users',
                'attributes': {
                    'id': user.id,
                    'type': user.type,
                    'provider': user.provider,
                    'token': user.token.decode(),
                    # 'refreshable': provider.refreshable, #TODO Implement refreshing
                }
            }
        })
Exemple #4
0
    async def _authenticate(self, data):
        namespace = manager.get_namespace(data['namespace'])
        collection = namespace.get_collection(data['collection'])

        if not UserPlugin.is_enabled(collection):
            raise exceptions.PluginNotEnabled(UserPlugin.NAME)

        if not (
            collection.schema
            and 'password' in collection.schema._schema.get('required', [])
            and collection.schema._schema['properties']['password'] == self.PASSWORD_SCHEMA
        ):
            raise exceptions.BadRequest(title='Bad password schema', detail='The schema for password must be {} and must be a required field'.format(self.PASSWORD_SCHEMA))

        # TODO validate retrieved document
        doc = collection.read(data['username'])
        password = doc.data['password'].encode()

        hashed = await asyncio.get_event_loop().run_in_executor(None, lambda: bcrypt.hashpw(data['password'].encode(), password))

        if hashed == password:
            return SelfAuthProvider.type, '{}:{}'.format(namespace.ref, collection.ref), data['username'], 8
        raise exceptions.Unauthorized()
Exemple #5
0
    def post(self, handler):
        if not self.template:
            raise exceptions.BadRequest(
                detail=
                'template must be provided via collection.plugins.template')

        if not self.from_email:
            raise exceptions.BadRequest(
                detail=
                'fromEmail must be provided via collection.plugins.fromEmail')

        if not handler.payload:
            raise exceptions.BadRequest()

        if not handler.payload.attributes.get('id'):
            raise exceptions.BadRequest(detail='Id must be provided')

        try:
            doc = self.collection.read(handler.payload.attributes['id'])
        except exceptions.NotFound:
            return handler.write({
                'data': {
                    'id': handler.payload.attributes.get('id'),
                    'type': 'reset',
                    'attributes': {
                        'status': 'success'
                    }
                }
            })

        email = doc.data.get(self.email_field, 'null')
        if re.match(EMAIL_RE, email) is None:
            raise exceptions.BadRequest(
                detail='"{}" at "{}" is not a valid email'.format(
                    email, self.email_field))

        namespace = handler._view._namespace  # A little hack never hurt anyone
        from jam.auth.providers.self import SelfAuthProvider
        user = User.create(SelfAuthProvider.type,
                           '{}:{}'.format(namespace.ref, self.collection.ref),
                           doc.ref,
                           exp=8)

        try:
            sg = sendgrid.SendGridClient(self.sendgrid_key, raise_errors=True)
            mail = sendgrid.Mail(to=email)

            mail.set_from(self.from_email)
            mail.add_substitution(':token', user.token.decode())
            mail.add_substitution(':user', user.id)
            mail.add_filter('templates', 'enable', 1)
            mail.add_filter('templates', 'template_id', self.template)
            # Sendgrid requires subject text and html to be set to a non falsey value
            # It is highly recommended that you overwrite these in your own templates
            mail.set_subject('JamDB password reset')
            mail.set_text('Your temporary token is :token')
            mail.set_html('Your temporary token is :token')

            logger.info(sg.send(mail))
        except sendgrid.SendGridError:
            logger.exception('Sendgrid Error:')
            raise exceptions.ServiceUnavailable(
                detail='Unable to submit request to sendgrid')

        return handler.write({
            'data': {
                'id': handler.payload.attributes.get('id'),
                'type': 'reset',
                'attributes': {
                    'status': 'success'
                }
            }
        })
Exemple #6
0
 def prerequisite_check(self):
     super().prerequisite_check()
     if not isinstance(self.collection._state._backend.raw_backend(),
                       get_backend('elasticsearch')):
         raise exceptions.BadRequest(
             detail='This collection does not support searching')