Esempio n. 1
0
	def __init__(self, status=500, message=None, code=None, **kwargs):
		self.code = status if code is None else code

		if message:
			self.message = message
		else:
			self.message = self.get_message(status) if code is None else self.get_error(code)

		Response.__init__(self, status, self.to_dict(), **kwargs)
		Exception.__init__(self, self.message)
Esempio n. 2
0
    async def post(self, request):
        user = await self.server.tools.authorize(
            request.headers.get('Authorization'),
            permissions=['OWNER'],
            bots=False)

        data = self.validate(await request.json(), required=['name'])

        if len(data['name']) > 32:
            raise InvalidUsage(400, 'Bot name too long')

        connection = await self.server.database.acquire()
        try:
            async with connection.cursor() as cur:
                await cur.execute('SELECT * FROM `bots` WHERE `name` = %s',
                                  (data['name'], ))
                if await cur.fetchone():
                    raise InvalidUsage(400, 'Bot name in use')

                bid = self.server.snowflake.generate()
                token = self.server.token.generate(bid)

                await cur.execute(
                    'INSERT INTO `bots` (`id`, `name`, `permissions`, `snowflake`, `secret`) VALUES (%s, %s, %s, %s, %s)',
                    (bid, data['name'], 0, token['snowflake'],
                     token['secret']))
        finally:
            self.server.database.release(connection)

        return Response(200, {'token': token['token']})
    async def get(self, request, itype, sid):
        bot = await self.server.tools.authorize(
            request.headers.get('Authorization'),
            bot_permissions=['OWNER'],
            bots=True)

        if itype not in self.allowed:
            raise InvalidUsage(400, 'Invalid Id Type')

        itype = ThresholdIdTypes.get(itype.upper()[:-1])

        thresholds = {}
        connection = await self.server.database.acquire()
        try:
            async with connection.cursor() as cur:
                if await cur.execute(
                        'SELECT * FROM `thresholds` WHERE `id` = %s AND `id_type` = %s',
                    (sid, itype.value)):
                    found = await cur.fetchone()
                    thresholds.update({
                        k.value: found[k.value]
                        for k in PerspectiveAttributes
                    })
                else:
                    raise InvalidUsage(
                        404, 'Thresholds not found for this id and id type')
        finally:
            self.server.database.release(connection)

        return Response(200, thresholds)
Esempio n. 4
0
    async def get(self, request):
        #implement using timestamp
        data = {}

        connection = await self.server.database.acquire()
        try:
            async with connection.cursor() as cur:
                await cur.execute(
                    ' '.join([
                        'SELECT', ', '.join([
                            '`count`', '`started`', ', '.join([
                                '`{}`'.format(attribute.value)
                                for attribute in PerspectiveAttributes
                            ])
                        ]), 'FROM `muck_averages` WHERE',
                        '`timestamp` = %s AND `context_type` = %s AND `context_id` = %s AND `user_id` = %s'
                    ]), [0, ContextTypes.GLOBAL.value, 0, 0])
                data['scores'] = await cur.fetchone()
                if not data['scores']:
                    raise InvalidUsage(404, 'No data found')

                data['count'] = data['scores'].pop('count')
                data['started'] = data['scores'].pop('started')
                for key in data['scores'].keys():
                    data['scores'][key] = round(
                        float(data['scores'][key]) / data['count'], 10)
        finally:
            self.server.database.release(connection)

        return Response(200, data)
Esempio n. 5
0
    async def get(self, request, uid):
        user = await self.server.tools.authorize(
            request.headers.get('Authorization'), bot_permissions=['OWNER'])

        if uid == '@me':
            if user['bot']:
                if not user.get('user'):
                    raise InvalidUsage(
                        400,
                        'Cannot use @me with bots without specifying user id in the token'
                    )

                uid = user['user']['id']
            else:
                uid = user['id']

        if uid != user.get('user', user)['id'] and not Permissions.check_any(
                user.get('user', user)['permissions'],
            ['OWNER', 'SUPERADMIN', 'ADMIN']):
            raise InvalidUsage(401)

        requested = {}
        connection = await self.server.database.acquire()
        try:
            async with connection.cursor() as cur:
                if user['bot'] and user.get(
                        'user', None) and uid == user['user']['id']:
                    requested.update(user['user'])
                elif not user['bot'] and uid == user['id']:
                    requested.update({
                        'id': user['id'],
                        'username': user['username'],
                        'discriminator': user['discriminator'],
                        'avatar_hash': user['avatar_hash'],
                        'refreshed': user['refreshed'],
                        'permissions': user['permissions']
                    })
                else:
                    await cur.execute('SELECT * FROM `users` WHERE `id` = %s',
                                      (uid, ))
                    requested.update(await cur.fetchone())

                #update information from discord if not requested from bot
        finally:
            self.server.database.release(connection)

        if not requested:
            raise InvalidUsage(404, 'User not found')
        else:
            requested['discriminator'] = '{:04}'.format(
                requested['discriminator'])
            return Response(200, requested)
Esempio n. 6
0
    async def get(self, request):
        user = await self.server.tools.authorize(
            request.headers.get('Authorization'))
        if user['bot']:
            raise InvalidUsage(401, 'Bots cannot use this endpoint.')

        connection = await self.server.database.acquire()
        try:
            async with connection.cursor() as cur:
                await cur.execute(
                    'DELETE FROM `token_sessions` WHERE `id` = %s',
                    (user['token']['snowflake'], ))
        finally:
            self.server.database.release(connection)

        return Response(204)
    async def put(self, request, itype, sid):
        bot = await self.server.tools.authorize(
            request.headers.get('Authorization'),
            bot_permissions=['OWNER'],
            bots=True)

        if itype not in self.allowed:
            raise InvalidUsage(400, 'Invalid Id Type')

        itype = ThresholdIdTypes.get(itype.upper()[:-1])

        data = self.validate(await request.json())

        thresholds = {}
        for key in data:
            threshold = PerspectiveAttributes.get(key.upper())
            if threshold:
                thresholds[threshold.value] = data[key]
            else:
                raise InvalidUsage(400, 'Invalid Attribute: {}'.format(key))

        connection = await self.server.database.acquire()
        try:
            async with connection.cursor() as cur:
                ithresholds = thresholds.items()
                await cur.execute(
                    ' '.join([
                        'INSERT INTO `thresholds`',
                        '(`id`, `id_type`, {})'.format(', '.join([
                            '`{}`'.format(k) for k, v in ithresholds
                        ])), 'VALUES', '(%s, %s, {})'.format(', '.join([
                            '%s' for a in range(len(thresholds))
                        ])), 'ON DUPLICATE KEY UPDATE', ', '.join([
                            '`{k}` = ROUND(VALUES(`{k}`), 2)'.format(k=k)
                            for k, v in ithresholds
                        ])
                    ]), [sid, itype.value] + [v for k, v in ithresholds])
        finally:
            self.server.database.release(connection)

        return Response(204)
Esempio n. 8
0
    async def post(self, request):
        try:
            data = self.validate(await request.json())
            token = self.server.token.split(data.get('token', None))
        except:
            raise InvalidUsage(400)

        connection = await self.server.database.acquire()
        try:
            async with connection.cursor() as cur:
                await cur.execute(
                    'SELECT * FROM `token_states` WHERE `id` = %s',
                    (token['user_id'], ))
                state = await cur.fetchone()
                if not state or not self.server.token.compare(
                        token['hmac'], state['snowflake'], state['secret']):
                    raise InvalidUsage(400)

                await cur.execute('SELECT `id` FROM `users` WHERE `id` = %s',
                                  state['user_id'])
                user = await cur.fetchone()
                if not user:
                    raise InvalidUsage(500, 'lol no user found')

                session_token = self.server.token.generate(user['id'])
                await cur.execute(
                    'INSERT INTO `token_sessions` (`id`, `user_id`, `secret`, `last_used`) VALUES (%s, %s, %s, %s)',
                    (session_token['snowflake'], user['id'],
                     session_token['secret'], 0))
                await cur.execute('DELETE FROM `token_states` WHERE `id` = %s',
                                  (token['user_id'], ))
        finally:
            self.server.database.release(connection)

        if session_token:
            return Response(200, {'token': session_token['token']})
        else:
            raise InvalidUsage(400)
Esempio n. 9
0
 async def get(self, request, bid):
     return Response(200, [])
Esempio n. 10
0
 async def options(self, request):
     return Response(204)
Esempio n. 11
0
    async def post(self, request):
        bot = await self.server.tools.authorize(
            request.headers.get('Authorization'), bots=True)

        if not self.perspective:
            raise InvalidUsage(500, 'Server missing perspective API key')

        store = bool(request.query.get('store', None) == 'true')

        data = self.validate(await request.json(), required=['content'])
        data['guild_id'] = data.get('guild_id', None)
        data['channel_id'] = data.get('channel_id', None)
        if store:
            if not Permissions.check(bot['permissions'], 'OWNER'):
                raise InvalidUsage(401)
            data = self.validate(
                data,
                required=['message_id', 'channel_id', 'user_id', 'timestamp'])
            data['edited'] = bool(data.get('edited', False))
            try:
                data['message_id'] = int(data['message_id'])
                data['channel_id'] = int(data['channel_id'])
                data['user_id'] = int(data['user_id'])
                data['timestamp'] = int(data['timestamp'])
            except:
                raise InvalidUsage(400)

        try:
            data['guild_id'] = data['guild_id'] and int(data['guild_id'])
            data['channel_id'] = data['channel_id'] and int(data['channel_id'])
        except:
            raise InvalidUsage(400)

        if not data['content']:
            #if they send in a blank content lol
            raise InvalidUsage(400)

        data['content'] = data['content'].lower()
        mhash = hashlib.sha256(data['content'].encode()).hexdigest()

        response = {}
        connection = await self.server.database.acquire()
        try:
            async with connection.cursor() as cur:
                if store:
                    if await cur.execute(
                            'SELECT * FROM `muck_messages` WHERE `message_id` = %s AND `timestamp` = %s AND `edited` = %s',
                        (data['message_id'], data['timestamp'],
                         data['edited'])):
                        raise InvalidUsage(400,
                                           'Message already inside database.')

                await cur.execute(
                    'SELECT * FROM `muck_cache` WHERE `hash` = %s', (mhash, ))
                scores = await cur.fetchone()

                if not scores or scores['analyzed'] < int(
                        time.time() - self.max_cache_timestamp):
                    http = await self.server.httpclient.googleapi_perspective(
                        self.perspective['token'], data['content'],
                        self.attributes, True)
                    if http['status'] != 200:
                        if not http['json']:
                            raise InvalidUsage(
                                http['status'],
                                'Google\'s API errored out with this status.')
                        else:
                            raise InvalidUsage(
                                http['status'],
                                http['data']['error']['message'])
                    http = http['data']

                    scores = {'hash': mhash}
                    for key in http['attributeScores'].keys():
                        scores[key.lower()] = round(
                            http['attributeScores'][key]['summaryScore']
                            ['value'], 10)

                    scores['analyzed'] = int(time.time())

                    iscores = scores.items()
                    await cur.execute(
                        ' '.join([
                            'INSERT INTO `muck_cache` ',
                            '({}) '.format(', '.join([
                                '`{}`'.format(k) for k, v in iscores
                            ])), 'VALUES ',
                            '({})'.format(', '.join(['%s'
                                                     for k, v in iscores])),
                            'ON DUPLICATE KEY UPDATE', ', '.join([
                                '`{k}` = VALUES(`{k}`)'.format(k=k)
                                for k, v in iscores if k != 'hash'
                            ])
                        ]), [v for k, v in iscores])

                response['hash'] = scores.pop('hash', mhash)
                response['analyzed'] = scores.pop('analyzed')
                response['scores'] = scores

                if store:
                    await cur.execute(
                        'INSERT INTO `muck_messages` (`message_id`, `guild_id`, `channel_id`, `user_id`, `hash`, `timestamp`, `edited`) VALUES (%s, %s, %s, %s, %s, %s, %s)',
                        (data['message_id'], data['guild_id'],
                         data['channel_id'], data['user_id'], mhash,
                         data['timestamp'], data['edited']))

                    self.server.loop.create_task(
                        self.average(data['timestamp'], data['guild_id'],
                                     data['channel_id'], data['user_id'],
                                     scores))

                if not store:
                    for ttype in ['guild', 'channel']:
                        tid = data.get('{}_id'.format(ttype), None)
                        if not tid:
                            continue

                        if await cur.execute(
                                'SELECT * FROM `thresholds` WHERE `id` = %s AND `id_type` = %s',
                            (tid, ThresholdIdTypes.get(ttype.upper()).value)):
                            thresholds = await cur.fetchone()
                            response[ttype] = {
                                'id': tid,
                                'passed': False,
                                'thresholds': {}
                            }
                            for attribute in thresholds:
                                if not scores.get(attribute) or not thresholds[
                                        attribute]:
                                    continue

                                if scores[attribute] >= thresholds[attribute]:
                                    response[ttype]['passed'] = True
                                    response[ttype]['thresholds'][
                                        attribute] = thresholds[attribute]
        finally:
            self.server.database.release(connection)

        if store:
            return Response(204)
        else:
            return Response(200, response)
Esempio n. 12
0
 async def site_discord(self, request):
     return Response(200, {'prefixes': ['.m', '.muck'], 'commands': []})
	async def get(self, request, itype, sid):
		if itype not in self.allowed_types:
			raise InvalidUsage(404)
		

		where = ['`timestamp` = %s']
		values = [0]

		if itype == 'guilds':
			where.append('`context_type` = %s')
			values.append(ContextTypes.GUILDS.value)
			
			where.append('`context_id` = %s')
			values.append(sid)
		elif itype == 'channels':
			where.append('`context_type` = %s')
			values.append(ContextTypes.CHANNELS.value)

			where.append('`context_id` = %s')
			values.append(sid)
		elif itype == 'users':
			where.append('`user_id` = %s')
			values.append(sid)

			context_id = request.query.get('context_id', None)
			context_type = request.query.get('context_type', None)

			if context_id is None or context_type is None:
				if context_id is None and context_type is None:
					context_id = 0
					context_type = ContextTypes.GLOBAL
				else:
					raise InvalidUsage(400, 'Context id and type cannot both be empty when one is passed in.')
			else:
				context_type = ContextTypes.get(context_type.upper())
				if not context_type:
					raise InvalidUsage(400, 'Invalid Context Type')
			
			where.append('`context_type` = %s')
			values.append(context_type.value)

			where.append('`context_id` = %s')
			values.append(context_id)
		
		response = {}
		connection = await self.server.database.acquire()
		try:
			async with connection.cursor() as cur:
				await cur.execute(
					' '.join([
						'SELECT',
						', '.join([
							'`count`',
							'`started`',
							', '.join([
								'`{}`'.format(attribute.value) for attribute in PerspectiveAttributes
							])
						]),
						'FROM `muck_averages` WHERE',
						' AND '.join(where)
					]),
					values
				)

				response['scores'] = await cur.fetchone()
				if not response['scores']:
					raise InvalidUsage(404, 'No data found')
				
				response['count'] = response['scores'].pop('count')
				response['started'] = response['scores'].pop('started')
				for key in response['scores'].keys():
					response['scores'][key] = round(float(response['scores'][key]) / response['count'], 10)
		finally:
			self.server.database.release(connection)
		
		return Response(200, response)