Exemplo n.º 1
0
    def new_beer_call(self, id_group, data):
        try:
            title = data.get('title')
            text = data.get('message')
            new_beer_call = datetime.now()
            last_beer_call = datetime.strptime(self.get_global(id_group).get('beer_call'), '%m-%d-%Y %H:%M:%S')
            if last_beer_call:
                time_diff = new_beer_call - last_beer_call
                if time_diff.seconds < 3600:
                    return Error('Not allowed to send notification, delay not great', 403).get_error()
            new_beer_call = new_beer_call.strftime('%Y-%m-%d %H:%M:%S')
            with self.con:
                cur = self.con.cursor(Model = UserGroup)
                sql = "UPDATE `groups` SET `beer_call` = %s WHERE id = %s"
                cur.execute(sql, (new_beer_call, id_group))
                self.con.commit()
                list_users = self.list_user_from_group(id_group)
                login_list = []
                for nb, user in list_users.items():
                    login_list.append(user.get('login'))
                tokens = UserView().list_tokens_from_logins(login_list)
                message = NotificationMessage({'title': title,
                                               'text': text})
                NotificationsView(message, tokens).send_push_message()

                return self.get(id_group)

        except Exception as e:
            print(e)
            self.con.rollback()
            return Error('Problem happened in updating user beer call in group', 400).get_error()
Exemplo n.º 2
0
    def delete(self, id_group, login):
        try:
            with self.con:
                cur = self.con.cursor(Model = Group)
                sql = "SELECT * FROM `groups` WHERE id=%s"
                cur.execute(sql, id_group)

                group = cur.fetchone()
                if group is None:
                    return Error('Not Found', 404).get_error()
                if group.to_json()['owner'] == login:
                    sql = "DELETE FROM `groups` WHERE id = %s AND owner=%s"
                    cur.execute(sql, (id_group,  login))
                    if cur.rowcount == 0:
                        return Error('User unauthorized to delete this group', 403).get_error()
                    self.con.commit()
                else:
                    return self.remove_from_group(id_group, login)

                return self.list(login)

        except Exception as e:
            print(e)
            self.con.rollback()
            return Error('Problem happened in group deletion', 400).get_error()
Exemplo n.º 3
0
def update_group(id, user=None):
    """Update a group"""
    try:
        data = json.loads(request.body.read())
        login = user.to_json().get('login')
        if data.get('invitation'):
            invitation_type = data.get('invitation')
            return GroupView().handle_invitation(id, login, invitation_type)
        if data.get('beer_call'):
            return GroupView().new_beer_call(id)
        if data.get('location_permission'):
            permission = bool(data.get('location_permission'))
            return GroupView().update_permission_location(id, login, permission)
        if data.get('location_sent'):
            try:
                location = Location(data.get('location_sent'))
            except Error as e:
                return Error('Wrong location attribute', 400)
            if GroupView().user_allow_location(id, user.to_json().get('login')):
                return GroupView().update_location(user.to_json().get('login'), location, id)
            else:
                return Error('User do not allow location', 403)

    except Exception as e:
        return e
Exemplo n.º 4
0
    def wrapper(*args, **kwargs):
        auth = request.headers.get('Authorization')
        if auth is None:
            return Error('Not Logged', 401).get_error()
        user = AuthTokenView().get(auth)

        if isinstance(user, dict):
            return user

        if not user.to_json()['isAdmin']:
            return Error('Not Admin', 403).get_error()

        return f(user=user, *args, **kwargs)
Exemplo n.º 5
0
    def autocomplete(self, query):
        try:
            with self.con:
                decoded_query = unquote(query)
                decoded_query = decoded_query.split(' ')
                words = []
                for word in decoded_query:
                    if len(word):
                        words.append(word)

                if not len(words):
                    return {}
                words = '|'.join(words)

                cur = self.con.cursor(Model= User)
                sql = "SELECT login, firstname, lastname, img_url, img_width, img_height FROM users_app WHERE login REGEXP %s  OR firstname REGEXP %s OR lastname REGEXP%s LIMIT 5"
                cur.execute(sql, (words, words,words))
                list_users = cur.fetchall()

                print(list_users)
                result = {}
                count = 0
                for user in list_users:
                    result[count] = user.to_json()
                    count +=1

                return result

        except Exception as e:
            print(e)
            response.status = 400
            return Error('Problem happened in query list', 501).get_error()
Exemplo n.º 6
0
    def list(self, list=None, mail=None):
        with self.con:
            try:
                cur = self.con.cursor(Model = User)
                if list is not None:
                    t = tuple(list)
                    lookup = f"IN {t}" if len(t) > 1 else f"='{t[0]}'"
                    sql = "Select login, lastname, firstname, email, password, isAdmin, ST_X(lastPosition) AS latitude, " \
                          f"ST_Y(lastPosition) AS longitude, push_token, img_url, img_width, img_height from users_app WHERE login {lookup}"
                else:
                    sql = "Select login, lastname, firstname, email, password, isAdmin, ST_X(lastPosition) AS latitude, " \
                          "ST_Y(lastPosition) AS longitude, push_token, img_url, img_width, img_height from users_app"
                cur.execute(sql)
                users = cur.fetchall()
                users_dict = {}
                count = 0
                for user in users:
                    users_dict[count] = user.to_json()
                    count += 1

                return users_dict

            except Exception as e:
                print(e)
                response.status = 400
                return Error('Problem happened in query list').get_error()
Exemplo n.º 7
0
    def reset_password(self):
        """
        generate a new password for the login and send it by mail
        """
        letters = string.ascii_lowercase
        new_pwd = ''.join(random.choice(letters) for i in range(10))

        try:
            with self.con:
                cur = self.con.cursor(Model = User)
                sql = "UPDATE users_app SET password=aes_encrypt(%s, %s) WHERE login=%s;"
                cur.execute(sql, (new_pwd, SALT, self.login))
                self.con.commit()
                email = self.get(self.login).to_json().get('email')
                msg = """
                Salut, participant.e à l'édition 2020 de SKI'UTC. Comme tu as pu le constater, cette année, <br>
                De la nouveauté cette année : une application SKI'UTC rien que pour toi, rien que pour vous ! <br>
                <br>
                Cours l'installer sur le store de ton téléphone (recherches SKI'UTC) <br>
                <br>
                Pour te connecter c'est simple : tu utilises ton login (ou email si tu es tremplin), et tu utilises ces codes :
                <br><br>
                <B>IDENTIFIANT : {}</B><br>
                <B>PASSWORD : {}</B><br>
                """.format(self.login, new_pwd)
                Mail().mail_sender(email, "Ton mot de passe pour l'application SKI'UTC", msg)
                return new_pwd

        except Exception as e:
            print(e)
            self.con.rollback()
            response.status = 400
            return Error('Error happened in password reset process').get_error()
Exemplo n.º 8
0
    def bot_account_verification(self, pwd):
        """
        check the login and pwd given to authenticate user
        save en give a token
        """
        try:
            with self.con:
                cur = self.con.cursor(Model = User)
                sql = "SELECT login, lastname, firstname, password FROM users_app WHERE login=%s and password=aes_encrypt(%s, %s)"
                cur.execute(sql, (self.login, pwd, SALT))
                user = cur.fetchone()

                if user is None:
                    return None
                return user.to_json()

        except Error as e:
            return e.get_error()

        except Exception as e:
            print(e)
            response.status = 400
            return Error('Authentication error').get_error()

        finally:
            cur.close()
            self.con.close()
Exemplo n.º 9
0
    def push_token(self, push_token):
        try:
            with self.con:
                try:
                    cur = self.con.cursor(Model=User)
                    sql = "UPDATE users_app SET `push_token`=%s WHERE login=%s"
                    cur.execute(sql, (push_token, self.login))
                    self.con.commit()

                except Exception as e:
                    self.con.rollback()
                    raise e

                sql = "SELECT login, lastname, firstname, email, password, isAdmin, ST_X(lastPosition), " \
                      "ST_Y(lastPosition), push_token FROM users_app WHERE login=%s"
                cur.execute(sql, self.login)
                user = cur.fetchone()

                return user.to_json()

        except Error as e:
            return e.get_error()

        except Exception as e:
            response.status = 501
            return Error('Problem happened in adding push token',
                         501).get_error()

        finally:
            self.con.close()
Exemplo n.º 10
0
    def create(self, data):
        try:
            with self.con:
                title = data.get('title')
                text = data.get('text')
                img_url = data.get('img_url')
                img_width = data.get('img_width')
                img_height = data.get('img_height')
                type = data.get('type')
                cur = self.con.cursor(Model=News)
                sql = "INSERT INTO news (title, text, img_url, img_width, img_height, date, type) VALUES (%s, %s, %s, %s, %s, %s, %s)"
                now = datetime.now()
                now = now.strftime('%Y-%m-%d %H:%M:%S')
                cur.execute(
                    sql,
                    (title, text, img_url, img_width, img_height, now, type))
                self.con.commit()
                sql = "SELECT * FROM news WHERE id = (SELECT MAX(id) FROM news)"
                cur.execute(sql)
                last = cur.fetchone()
                tokens = UserView().list_tokens()
                message = NotificationMessage(data)
                NotificationsView(message, tokens).send_push_message()
                if type == 'email':
                    list_mail = UserView().list_mail()
                    Mail().massive_mail_sender(list_mail, title, text)

                return last.to_json()

        except Exception as e:
            print(e)
            self.con.rollback()
            return Error('Problem happened in news creation', 400).get_error()
Exemplo n.º 11
0
    def handle_invitation(self, id_group, login, invitation_type):
        try:
            if invitation_type == 'V':
                with self.con:
                    cur = self.con.cursor(Model = UserGroup)
                    sql = "UPDATE `usergroup` SET status = 'V' WHERE `id_group` = %s AND `login_user` = %s"
                    cur.execute(sql, (id_group, login))
                    self.con.commit()
                    group = self.get_global(id_group)
                    group['user_status'] = 'V'

                    return self.list(login)
            else:
                with self.con:
                    cur = self.con.cursor(Model=UserGroup)
                    sql = "DELETE FROM `usergroup` WHERE `id_group` = %s AND `login_user` = %s"
                    cur.execute(sql, (id_group, login))
                    self.con.commit()

                    return self.list(login)

        except Exception as e:
            print(e)
            self.con.rollback()
            return Error('Problem happened in updating user status in group', 400).get_error()
Exemplo n.º 12
0
    def list_user_from_group(self, id_group, accept_only=False):
        try:
            with self.con:
                cur = self.con.cursor(Model = UserGroup)
                accept_sql = f"AND `status`= 'V'" if accept_only else ""
                sql = f"SELECT * from `usergroup` WHERE `id_group` = %s {accept_sql}"
                cur.execute(sql, id_group)
                users_group = cur.fetchall()
                ug_dict = {}
                login_list = []
                for user in users_group:
                    user = user.to_json()
                    ug_dict[user['login_user']] = user
                    login_list.append(user['login_user'])

                users = UserView().list(list=login_list)
                for user_key in users:
                    user = users[user_key]
                    user_group = ug_dict.get(user['login'])

                    user['status'] = user_group['status']
                    user['expiration_date'] = user_group['expiration_date']

                    if user_group['share_position']:
                        user['location'] = UserView(user['login']).get_location()

                    users[user_key] = user

                return users

        except Exception as e:
            print(e)
            return Error('Problem happened in query list', 400).get_error()
Exemplo n.º 13
0
    def rm_sys_disk(self, raise_exception=False):
        """
        删除系统盘,需要先删除所有系统盘快照

        :param raise_exception: 删除错误时是否抛出错误
        :return:
            True    # success
            False   # failed

        :raises: Error    # When raise_exception == True
        """
        if not self.disk:
            return True

        config = self.get_ceph_cluster()
        if not config:
            return False

        try:
            remove_image(ceph=config, pool_name=self.ceph_pool, image_name=self.disk)
        except Error as e:
            if raise_exception:
                raise Error(msg=str(e))

            return False

        self.disk = ''
        try:
            self.save(update_fields=['disk'])
        except Exception as e:
            pass

        return True
Exemplo n.º 14
0
    def get(self, token):
        """
        return the auth token if exist
        """
        with self.con:
            try:
                cur = self.con.cursor(Model=AuthToken)
                sql = "SELECT * FROM auth_token WHERE token=%s"
                cur.execute(sql, token)

                authentication = cur.fetchone()

                if authentication is None:
                    raise Error('Not logged', 403)

                authentication = authentication.to_json()
                user = UserView(authentication['login']).get()

                return user

            except Error as e:
                return e.get_error()

            except Exception as e:
                return e
Exemplo n.º 15
0
    def list(self, admin=False):
        try:
            with self.con:
                cur = self.con.cursor(Model=Potin)
                if admin:
                    sql = "SELECT * from potin WHERE approved = 0 ORDER BY id DESC"
                else:
                    sql = "SELECT * from potin WHERE approved = 1 ORDER BY id DESC"
                cur.execute(sql)
                response = cur.fetchall()
                count = 0
                result = {}
                for value in response:
                    potin = value.to_json()
                    #check if anonymous
                    if potin.get('isAnonymous'):
                        potin['sender'] = None
                    result[count] = potin
                    count += 1

                return result

        except Exception as e:
            print(e)
            return Error('Problem happen in query list').get_error()
Exemplo n.º 16
0
async def import_(client: Client, db: Database,
                  msg: Message) -> KanTeXDocument:
    """Import a CSV to the banlist.

    The CSV file should end in .csv and have a `id` and `reason` column

    Examples:
        {cmd}
    """
    if msg.is_reply:  # pylint: disable = R1702
        reply_msg: Message = await msg.get_reply_message()
        if reply_msg.document:
            _, ext = os.path.splitext(
                reply_msg.document.attributes[0].file_name)
            if ext == '.csv':
                data = await reply_msg.download_media(bytes)
                start_time = time.time()
                _banlist = await helpers.rose_csv_to_dict(data)
                if _banlist:
                    await db.banlist.upsert_multiple(_banlist)
                    if client.sw and client.sw.permission in [
                            Permission.Admin, Permission.Root
                    ]:
                        bans = {}
                        for b in _banlist:
                            bans[b['reason']] = bans.get(b['reason'],
                                                         []) + [b['id']]
                        admin_id = (await client.get_me()).id
                        for reason, uids in bans.items():
                            uids_copy = uids[:]
                            while uids_copy:
                                client.sw.add_bans([
                                    Ban(int(uid), reason, admin_id)
                                    for uid in uids_copy[:SWAPI_SLICE_LENGTH]
                                ])
                                uids_copy = uids_copy[SWAPI_SLICE_LENGTH:]

                stop_time = time.time() - start_time
                return KanTeXDocument(
                    Section('Import Result',
                            f'Added {len(_banlist)} entries.'),
                    Italic(f'Took {stop_time:.02f}s'))
            else:
                raise Error('File is not a CSV')
        else:
            raise Error('Need to reply to a document')
Exemplo n.º 17
0
    def delete(self, id_group, login):
        try:
            with self.con:
                cur = self.con.cursor(Model=Group)
                sql = "DELETE FROM `groups` WHERE id = %s AND owner=%s"
                cur.execute(sql, (id_group, login))
                if cur.rowcount == 0:
                    return Error('User unauthorized to delete this group',
                                 403).get_error()
                self.con.commit()

                return self.list(login)

        except Exception as e:
            print(e)
            self.con.rollback()
            return Error('Problem happened in group deletion', 400).get_error()
Exemplo n.º 18
0
    def verify_token(self, token, challenge):
        try:
            if token == WEBHOOK_TOKEN:
                return challenge
            raise Error("Bad token.", 400)

        except Exception as e:
            print(e)
            return e.get_error()
Exemplo n.º 19
0
async def query(args, kwargs, db: Database) -> KanTeXDocument:
    """Query a blacklist for a specific code.

    Blacklist names are _not_ the hexadecimal short hands

    Arguments:
        `type`: One of the possible autobahn types (See {prefix}ab)
        `code`: The index of the item, can be a range
        `-retired`: Show retired items

    Examples:
        {cmd} domain 3
        {cmd} channel 4..20
        {cmd} channel
    """
    item_type = kwargs.get('type')
    code = kwargs.get('code')

    if item_type is None and args:
        item_type = args[0]
    else:
        raise Error('No blacklist name specified')
    if code is None and len(args) > 1:
        code = args[1]

    hex_type = None
    blacklist = None
    if item_type is not None:
        hex_type = AUTOBAHN_TYPES.get(item_type, item_type)
        blacklist = await db.blacklists.get(hex_type)

    blacklist_items = await blacklist.get_all()

    if code is not None:
        if isinstance(code, int):
            code = [code]
        all_items = await blacklist.get_indices(list(code)[:MAX_QUERY_ITEMS])
    else:
        all_items = blacklist_items

    retired = kwargs.get('retired', len(all_items) == 1)
    if not retired:
        all_items = [i for i in all_items if not i.retired]

    items = []
    for item in all_items[:MAX_QUERY_ITEMS]:
        kvitem = KeyValueItem(
            item.index,
            f"{Code(item.value)} {Italic('(retired)') if item.retired else ''}"
        )
        items.append(kvitem)

    return KanTeXDocument(
        Section(f'Items for type: {item_type}[{hex_type}]', *items
                or [Italic('None')]),
        Italic(f'Total count: {len(blacklist_items)}')
        if blacklist_items else None)
Exemplo n.º 20
0
def create_news(user=None):
    """create a news"""
    try:
        data = json.loads(request.body.read())
        if not data.get('title') or not data.get('text'):
            return Error('Title or text empty', 400).get_error()
        return NewsView().create(data)
    except Exception as e:
        return e
Exemplo n.º 21
0
async def importjustasic_(client: Client, db: Database, msg: Message,
                          chat: Channel, args, kwargs) -> KanTeXDocument:
    """Import a CSV to the banlist.

    Made to import a fuckming printed python list


    who even does this

    Examples:
        {cmd}
    """
    reasontoban = kwargs.get('reason')
    if msg.is_reply:  # pylint: disable = R1702
        reply_msg: Message = await msg.get_reply_message()
        if not reply_msg.document:
            raise Error('Need to reply to a document')
        _, ext = os.path.splitext(reply_msg.document.attributes[0].file_name)
        if ext != '.txt':
            raise Error('File is not a txxxt')
        data = await reply_msg.download_media(bytes)
        start_time = time.time()
        _banlist = await helpers.id_csv_to_dict(data)
        if _banlist:

            progress_message: Message = await client.send_message(
                chat, f"Processing {len(_banlist)} User IDs")
            while _banlist:
                uid_batch = _banlist[:CHUNK_SIZE]
                for uid in uid_batch:
                    await client.ungban(uid)

                _banlist = _banlist[CHUNK_SIZE:]
                if _banlist:
                    if progress_message:
                        await progress_message.edit(
                            f"Sleeping for 10 seconds after banning {len(uid_batch)} Users. {len(_banlist)} Users left."
                        )
                    await asyncio.sleep(10)

        stop_time = time.time() - start_time
        return KanTeXDocument(
            Section('Import Result', f'Added {len(_banlist)} entries.'),
            Italic(f'Took {stop_time:.02f}s'))
Exemplo n.º 22
0
def send_invitation(id, user=None):
    """send invitation to user/s for a group"""
    try:
        data = json.loads(request.body.read())
        if not data.get('list_login'):
            return Error('No login provided - invitation is cancelled', 400)
        login_list = data.get('list_login')
        return GroupView().add_to_group(id, login_list=login_list)

    except Exception as e:
        return e
Exemplo n.º 23
0
def verification():
    try:
        data = request.query
        verify_token = data.get('hub.verify_token')
        challenge = data.get('hub.challenge')

        if challenge is None or verify_token is None:
            return Error('No data', 400)
        return BotView().verify_token(verify_token, challenge)
    except Exception as e:
        return e
Exemplo n.º 24
0
    def authenticate(self, pwd):
        """
        check the login and pwd given to authenticate user
        save en give a token
        """
        try:
            with self.con:
                cur = self.con.cursor(Model = User)
                sql = "SELECT login, lastname, firstname, email, password, isAdmin, ST_X(lastPosition) AS latitude, " \
                      "ST_Y(lastPosition) as longitude, push_token, img_url, img_width, img_height FROM users_app WHERE login=%s and password=aes_encrypt(%s, %s)"
                cur.execute(sql, (self.login, pwd, SALT))
                user = cur.fetchone()
                if user is None:
                    raise Error('Authentication error', 400)
                token = secrets.token_hex(25)
                try:
                    sql = "DELETE FROM auth_token WHERE login=%s"
                    cur.execute(sql, self.login)
                    sql = "INSERT INTO auth_token (login, token) VALUES (%s, %s)"
                    cur.execute(sql, (self.login, token))
                    self.con.commit()

                    json_user = user.to_json()
                    json_user['push_token'] = user.get_push_token()
                    return {'user': json_user, 'token': token}

                except Exception as e:
                    self.con.rollback()
                    raise Error('Authentication error', 400)

        except Error as e:
            return e.get_error()

        except Exception as e:
            print(e)
            response.status = 400
            return Error('Authentication error').get_error()

        finally:
            cur.close()
            self.con.close()
Exemplo n.º 25
0
def authentication():
    """authenticate user"""
    try:
        data = json.loads(request.body.read())
        login = data.get('login')
        password = data.get('password')
        if not login or not password:
            return Error('Login or Password empty', 400).get_error()
        return UserView(login).authenticate(password)

    except Exception as e:
        return e
Exemplo n.º 26
0
def create_bot_message(user=None):
    try:
        data = json.loads(request.body.read())
        text = data.get('text')
        type = data.get('type', 'text')

        if not text:
            return Error('no data', 400).get_error()
        return BotView().add_message(text, type)

    except Exception as e:
        return e
Exemplo n.º 27
0
    def get_top_users(self):
        if not self.admin:
            return Error('Not admin', 403).get_error()
        result = {}
        count = 0
        try:
            cur = self.con.cursor(Model=AnimationUser)
            sql = "SELECT * from `piste_anim` ORDER BY `level` DESC LIMIT 10"
            cur.execute(sql)
            response = cur.fetchall()
            if response is None:
                return {}
            for u in response:
                current = u.to_json()
                result[count] = current
                count += 1
            return result

        except Exception as e:
            print(e)
            return Error('Problem happened in query get', 400).get_error()
Exemplo n.º 28
0
    def add_to_group(self, id_group, login_list=None, owner=None, group=None):
        result = {}
        count = 0
        try:
            with self.con:

                if group is None:
                    group = self.get_global(id_group)

                if owner:
                    cur = self.con.cursor(Model=UserGroup)
                    sql = "INSERT INTO `usergroup` (`login_user`, `id_group`, `status`) VALUES (%s, %s, %s)"
                    cur.execute(sql, (owner, id_group, 'V'))
                    sql = "SELECT * FROM `usergroup` WHERE `id_group` = %s AND `login_user` = %s "
                    cur.execute(sql, (id_group, owner))
                    last = cur.fetchone()
                    result[count] = last.to_json()
                    count += 1
                if login_list:
                    for login in login_list:
                        try:
                            cur = self.con.cursor(Model=UserGroup)
                            sql = "INSERT INTO `usergroup` (`login_user`, `id_group`) VALUES (%s, %s)"
                            cur.execute(sql, (login, id_group))
                            sql = "SELECT * FROM `usergroup` WHERE `id_group` = %s AND `login_user` = %s"
                            cur.execute(sql, (id_group, login))
                            last = cur.fetchone()
                            result[count] = last.to_json()
                            count += 1

                        except Exception as e:
                            print(e)
                            code, message = e.args
                            if code == pymysql.constants.ER.DUP_ENTRY:
                                result[count] = {'error': message}
                                count += 1
                            else:
                                self.con.rollback()
                                raise e

                    tokens = UserView().list_tokens_from_logins(login_list)
                    message = NotificationMessage({
                        'title': 'Invitation de groupe - {}'.format(group.get('name')),
                        'text': '{} t\'a invité à rejoindre son nouveau groupe !'.format(group.get('owner'))
                        })
                    NotificationsView(message, tokens).send_push_message()

        except Exception as e:
            print(e)
            return Error('Problem happened when adding to group', 400).get_error()

        return result
Exemplo n.º 29
0
def create_potin(user=None):
    """create a potin"""
    try:
        data = json.loads(request.body.read())
        data["approved"] = False
        data["sender"] = user.to_json().get("login")
        if not data.get('title') or not data.get('text'):
            return Error('Title or text empty', 400).get_error()

        return PotinView().create(data)

    except Exception as e:
        return e
Exemplo n.º 30
0
def create_group(user=None):
    """création d'un groupe"""
    try:
        data = json.loads(request.body.read())
        if not data.get('name'):
            return Error('Please provide a name', 400)
        name = data.get('name')
        owner = user.to_json().get('login')
        list_login = data.get('list_login')
        return GroupView(owner).create(name, owner, list_login)

    except Exception as e:
        return e