Ejemplo n.º 1
0
    def patch(self: Controller):
        """
        Set context.method
        Set context.form
        :return:
        """
        # Preserve patches
        patches = context.form
        results = []
        context.jsonpatch = True

        try:
            for patch in patches:
                context.form = patch.get('value', {})
                context.method = patch['op']

                remaining_paths = patch['path'].split('/')
                if remaining_paths and not remaining_paths[0]:
                    return_data = self()
                else:
                    return_data = self(*remaining_paths)

                results.append(return_data)

                DBSession.flush()
            DBSession.commit()
            return '[%s]' % ',\n'.join(results)
        except:
            if DBSession.is_active:
                DBSession.rollback()
            raise
        finally:
            del context.jsonpatch
Ejemplo n.º 2
0
    def post(self):
        email = context.form.get('email')
        password = context.form.get('password')
        otp = context.form.get('otp', None)

        principal = context.application.__authenticator__.login((email, password))
        token = principal.dump().decode()

        try:
            # TODO: Add this feature for admins
            if principal.is_in_roles('client'):
                client = Client.query.filter(Client.email == email).one()
                if client.has_second_factor is True:
                    if otp is None:
                        raise HttpBadRequest('Otp needed', 'bad-otp')

                    oath = Oath(seed=settings.membership.second_factor_seed, derivate_seed_from=client.email)
                    is_valid, _ = oath.verify_google_auth(otp)
                    if is_valid is False:
                        raise HttpBadRequest('Invalid otp', 'invalid-otp')

            login_log = SecurityLog.generate_log(type='login')
            DBSession.add(login_log)
            DBSession.flush()
        except Exception as e:
            # FIXME: Fix the warning
            context.application.__authenticator__.unregister_session(principal.session_id)
            raise e

        return dict(token=token)
Ejemplo n.º 3
0
    def send(self, target_id):
        mimetype = context.form.get('mimetype')
        sender = Member.current()
        message = Message(body=context.form.get('body'))
        message.target_id = int(target_id)
        message.sender_id = sender.id

        if 'attachment' in context.form:
            message.attachment = context.form.get('attachment')
            message.mimetype = message.attachment.content_type

            if message.attachment.content_type in BLACKLIST_MIME_TYPES:
                raise HTTPUnsupportedMediaType()

        elif mimetype:
            if mimetype not in SUPPORTED_TEXT_MIME_TYPES:
                raise HTTPUnsupportedMediaType()

            message.mimetype = context.form.get('mimetype')

        else:
            message.mimetype = 'text/plain'

        DBSession.add(message)
        DBSession.flush()
        queues.push(settings.messaging.workers_queue, message.to_dict())
        webhook = Webhook()
        webhook.sent_message(target_id, sender.reference_id)
        return message
Ejemplo n.º 4
0
    def subscribe(self):
        member = Member.current()
        query = DBSession.query(Room)
        requested_rooms = Target.filter_by_request(query).all()

        if len(requested_rooms) >= settings.room.subscription.max_length:
            raise HTTPStatus(
                f'716 Maximum {settings.room.subscription.max_length} Rooms '
                f'To Subscribe At A Time')

        requested_rooms_id = {i.id for i in requested_rooms}

        subscribed_rooms = DBSession.query(TargetMember) \
            .filter(TargetMember.member_id == member.id) \
            .join(Target, Target.id == TargetMember.target_id) \
            .filter(Target.type == 'room') \
            .all()
        subscribed_rooms_id = {i.target_id for i in subscribed_rooms}
        not_subscribed_rooms_id = requested_rooms_id - subscribed_rooms_id

        flush_counter = 0
        for each_room_id in not_subscribed_rooms_id:
            flush_counter += 1
            target_member = TargetMember(target_id=each_room_id,
                                         member_id=member.id)
            DBSession.add(target_member)
            if flush_counter % 10 == 0:
                DBSession.flush()

        not_subscribed_rooms = DBSession.query(Target) \
            .filter(Target.id.in_(not_subscribed_rooms_id))
        return not_subscribed_rooms
Ejemplo n.º 5
0
 def append(self, listtitle, itemtitle):
     me = self._get_current_user()
     item = Item(
         ownerid=context.identity.id,
         list=listtitle,
         title=itemtitle
     )
     me.items.append(item)
     DBSession.flush()
     return ''.join((str(item), CR))
Ejemplo n.º 6
0
def insert_departments():  # pragma: no cover
    department1 = TicketDepartment()
    department1.title = 'Test Department 1'
    DBSession.add(department1)

    department2 = TicketDepartment()
    department2.title = 'Test Department 2'
    DBSession.add(department2)

    department3 = TicketDepartment()
    department3.title = 'Test Department 3'
    DBSession.add(department3)
    DBSession.flush()
Ejemplo n.º 7
0
    def obtain(self):
        # FIXME: Validation and prevent form.
        cas_server = CASClient()
        access_token, member_id = cas_server \
            .get_access_token(context.form.get('authorizationCode'))

        member = cas_server.get_member(access_token)
        user = DBSession.query(Member) \
            .filter(Member.email == member['email']) \
            .one_or_none()

        if user is None:
            user = Member(
                email=member['email'],
                title=member['title'],
                first_name=member['firstName'],
                last_name=member['lastName'],
                access_token=access_token,
                reference_id=member['id'],
                avatar=member['avatar'],
            )

        if user.title != member['title']:
            user.title = member['title']

        if user.first_name != member['firstName']:
            user.first_name = member['firstName']

        if user.avatar != member['avatar']:
            user.avatar = member['avatar']

        if user.access_token != access_token:
            user.access_token = access_token

        if user.last_name != member['lastName']:
            user.last_name = member['lastName']

        DBSession.add(user)
        DBSession.flush()
        principal = user.create_jwt_principal()
        context.response_headers.add_header('X-New-JWT-Token',
                                            principal.dump().decode('utf-8'))

        return dict(token=principal.dump().decode('utf-8'))
Ejemplo n.º 8
0
    def create(self):
        title = context.form.get('title')
        department_id = context.form.get('departmentId')
        message = context.form.get('message')
        attachment = context.form.get('attachment', None)
        client_id = context.form.get('clientId', None)

        if TicketDepartment.query.filter(
                TicketDepartment.id == department_id).count() == 0:
            raise HttpBadRequest('Bad department_id')

        ticket = Ticket()
        ticket.member_id = context.identity.id if context.identity.is_in_roles(
            'client') else client_id
        ticket.department_id = department_id
        ticket.title = title

        ticket_message = TicketMessage()
        ticket_message.ticket = ticket
        ticket_message.member_id = context.identity.id
        ticket_message.text = message

        try:
            ticket_message.attachment = attachment

        except AspectRatioValidationError as ex:
            raise HttpBadRequest(str(ex), reason='invalid-aspectratio')

        except DimensionValidationError as ex:
            raise HttpBadRequest(str(ex), reason='invalid-dimensions')

        except (AnalyzeError, ContentTypeValidationError) as ex:
            raise HttpBadRequest(str(ex), reason='invalid-type')

        DBSession.add(ticket)
        DBSession.add(ticket_message)

        # FIXME: These are not good:
        DBSession.flush()
        result = ticket.to_dict()
        result['firstMessage'] = ticket_message.to_dict()

        return result
Ejemplo n.º 9
0
    def edit(self, id):
        id = int_or_notfound(id)
        new_message_body = context.form.get('body')

        message = DBSession.query(Message).get(id)
        if message is None:
            raise HTTPNotFound()

        if message.is_deleted:
            raise HTTPStatus('616 Message Already Deleted')

        if message.sender_id != Member.current().id:
            raise HTTPForbidden()

        message.body = new_message_body
        DBSession.add(message)
        DBSession.flush()
        queues.push(settings.messaging.workers_queue, message.to_dict())
        return message
Ejemplo n.º 10
0
    def patch(self: Controller):
        """
        Set context.method
        Set context.form
        :return:
        """
        # Preserve patches
        patches = context.form
        results = []
        context.jsonpatch = True

        try:
            for patch in patches:
                context.form = patch.get('value', {})
                path, context.query = split_path(patch['path'])
                context.method = patch['op'].lower()
                context.request_content_length = \
                    len(context.form) if context.form else 0

                remaining_paths = path.split('/')
                if remaining_paths and not remaining_paths[0]:
                    return_data = self()
                else:
                    return_data = self(*remaining_paths)

                if isinstance(return_data, types.GeneratorType):
                    results.append('"%s"' % ''.join(list(return_data)))
                else:
                    results.append(return_data)

                DBSession.flush()
                context.query = {}

            DBSession.commit()
            return '[%s]' % ',\n'.join(results)
        except:
            if DBSession.is_active:
                DBSession.rollback()
            raise
        finally:
            del context.jsonpatch
Ejemplo n.º 11
0
    def reply(self, message_id):
        id = int_or_notfound(message_id)
        mimetype = context.form.get('mimetype')

        requested_message = DBSession.query(Message).get(id)
        if requested_message is None:
            raise HTTPNotFound()

        if requested_message.is_deleted:
            raise HTTPStatus('616 Message Already Deleted')

        message = Message(
            body=context.form.get('body'),
            target_id=requested_message.target_id,
            sender_id=Member.current().id,
            reply_to=requested_message,
        )

        if 'attachment' in context.form:
            message.attachment = context.form.get('attachment')
            message.mimetype = message.attachment.content_type

            if message.attachment.content_type in BLACKLIST_MIME_TYPES:
                raise HTTPUnsupportedMediaType()

        elif mimetype:
            if mimetype not in SUPPORTED_TEXT_MIME_TYPES:
                raise HTTPUnsupportedMediaType()

            message.mimetype = mimetype

        else:
            message.mimetype = 'text/plain'

        DBSession.add(message)
        DBSession.flush()
        queues.push(settings.messaging.workers_queue, message.to_dict())
        return message
Ejemplo n.º 12
0
    def delete(self, id):
        try:
            id = int(id)
        except:
            raise HTTPStatus('707 Invalid MessageId')

        message = DBSession.query(Message) \
            .filter(Message.id == id) \
            .one_or_none()
        if message is None:
            raise HTTPStatus('614 Message Not Found')

        if message.is_deleted:
            raise HTTPStatus('616 Message Already Deleted')

        if not message.sender_id == Member.current().id:
            raise HTTPForbidden()

        message.body = 'This message is deleted'
        message.mimetype = 'text/plain'
        message.soft_delete()
        DBSession.flush()
        queues.push(settings.messaging.workers_queue, message.to_dict())
        return message
Ejemplo n.º 13
0
def insert():  # pragma: no cover

    # Currencies
    tirr = Fiat(symbol='TIRR',
                name='Iran Rial',
                normalization_scale=-8,
                smallest_unit_scale=0)

    tbtc = Cryptocurrency(symbol='TBTC',
                          name='Bitcoin',
                          wallet_id="TBTC",
                          normalization_scale=0,
                          smallest_unit_scale=-8)

    teth = Cryptocurrency(symbol='TETH',
                          name='Ethereum',
                          wallet_id="TETH",
                          normalization_scale=-1,
                          smallest_unit_scale=-18)

    ttry = Fiat(symbol='TTRY',
                name='Turkish Lita',
                normalization_scale=-4,
                smallest_unit_scale=-2)

    # Markets
    tirr_tbtc = Market(name='TIRR_TBTC',
                       base_currency=tbtc,
                       quote_currency=tirr)
    tirr_teth = Market(name='TIRR_TETH',
                       base_currency=teth,
                       quote_currency=tirr)
    tbtc_teth = Market(name='TBTC_TETH',
                       base_currency=teth,
                       quote_currency=tbtc)
    ttry_tbtc = Market(name='TTRY_TBTC',
                       base_currency=tbtc,
                       quote_currency=ttry)
    DBSession.add(tirr_tbtc)
    DBSession.add(tirr_teth)
    DBSession.add(tbtc_teth)
    DBSession.add(ttry_tbtc)

    # Territories
    iran = Country(name='Iran', code='ir', phone_prefix=98)
    tehran_state = State(name='Tehran', country=iran)
    tehran_city = City(name='Tehran', state=tehran_state)
    turkey = Country(name='Turkey', code='tr', phone_prefix=90)
    ankara_state = State(name='Ankara', country=turkey)
    istanbul_state = State(name='Istanbul', country=turkey)
    istanbul_avrupa_city = City(name='Istanbul (Avrupa)', state=istanbul_state)
    istanbul_asia_city = City(name='Istanbul (Asia)', state=istanbul_state)
    ankara_city = City(name='Tehran', state=ankara_state)
    DBSession.add(tehran_city)
    DBSession.add(istanbul_avrupa_city)
    DBSession.add(istanbul_asia_city)
    DBSession.add(ankara_city)
    DBSession.flush()

    # Payment Gateways
    shaparak = PaymentGateway()
    shaparak.name = "tshaparak"
    shaparak.fiat_symbol = "TIRR"
    # shaparak.cashin_min = Decimal('10000'),
    # shaparak.cashin_max = Decimal('0'),
    # shaparak.cashin_static_commission = Decimal('0'),
    # shaparak.cashin_commission_rate = '0.0',
    # shaparak.cashin_max_commission = Decimal('0'),
    DBSession.add(shaparak)
    DBSession.flush()

    # Members
    admin1 = Admin()
    admin1.email = '*****@*****.**'
    admin1.password = '******'
    admin1.is_active = True
    DBSession.add(admin1)
    client1 = Client()
    client1.email = '*****@*****.**'
    client1.password = '******'
    client1.is_active = True
    DBSession.add(client1)
    DBSession.flush()

    # Ticketing Departments
    verification_department = TicketDepartment()
    verification_department.title = 'Verification'
    DBSession.add(verification_department)
    financial_department = TicketDepartment()
    financial_department.title = 'Financial'
    DBSession.add(financial_department)
    technical_department = TicketDepartment()
    technical_department.title = 'Technical'
    DBSession.add(technical_department)
    general_department = TicketDepartment()
    general_department.title = 'General'
    DBSession.add(general_department)
    DBSession.flush()
Ejemplo n.º 14
0
    def create(self):
        # TODO: Add some salt to prevent man in the middle (Extra field to send on creation and check on verification,
        # Use description part)
        amount = context.form.get('amount')
        shetab_address_id = context.form.get('shetabAddressId')

        # Check deposit range
        payment_gateway = PaymentGateway.query.filter(
            PaymentGateway.name == context.form.get(
                'paymentGatewayName')).one_or_none()

        amount = payment_gateway.fiat.input_to_normalized(amount)

        # TODO: More strict check and review how we control payment gateways
        if (payment_gateway is None) or (payment_gateway.fiat_symbol
                                         not in ['IRR', 'TIRR']):
            raise HttpBadRequest('Bad payment gateway')
        Fiat.query.filter(Fiat.symbol == payment_gateway.fiat_symbol).one()

        if (payment_gateway.cashin_max != Decimal(0) and amount > payment_gateway.cashin_max) \
                or amount < payment_gateway.cashin_min:
            raise HttpBadRequest('Amount is not between valid cashin range.')

        # Check sheba
        target_shetab = BankCard.query \
            .filter(BankCard.id == shetab_address_id) \
            .filter(BankCard.client_id == context.identity.id) \
            .one_or_none()

        if target_shetab is None:
            raise HttpBadRequest('Shetab address not found.')

        if target_shetab.is_verified is False:
            raise HttpConflict('Shetab address is not verified.')

        # Check commission
        commission = payment_gateway.calculate_cashin_commission(amount)

        if commission >= amount:
            raise HttpConflict('Commission is more than the amount')

        shaparak_in = Cashin()
        shaparak_in.member_id = context.identity.id
        shaparak_in.fiat_symbol = payment_gateway.fiat_symbol
        shaparak_in.amount = amount
        shaparak_in.commission = commission
        shaparak_in.banking_id = target_shetab
        shaparak_in.transaction_id = ''
        shaparak_in.payment_gateway_name = payment_gateway.name

        DBSession.add(shaparak_in)
        DBSession.flush()

        shaparak_provider = create_shaparak_provider()
        try:
            shaparak_in.transaction_id = shaparak_provider.create_transaction(
                batch_id=shaparak_in.id, amount=amount)
        except ShaparakError:
            raise HttpBadRequest('Transaction could not be created')

        return shaparak_in
Ejemplo n.º 15
0
def insert():  # pragma: no cover
    insert_departments()

    iran = Country(name='Iran', code='ir', phone_prefix=98)
    tehran_state = State(name='Tehran', country=iran)
    tehran_city = City(name='Tehran', state=tehran_state)

    DBSession.add(tehran_city)
    DBSession.flush()

    # Members
    admin1 = Admin()
    admin1.email = '*****@*****.**'
    admin1.password = '******'
    admin1.is_active = True
    DBSession.add(admin1)

    client1 = Client()
    client1.email = '*****@*****.**'
    client1.password = '******'
    client1.is_active = True
    DBSession.add(client1)

    client2 = Client()
    client2.email = '*****@*****.**'
    client2.password = '******'
    client2.is_active = True
    client2.is_email_verified = True
    DBSession.add(client2)

    client3 = Client()
    client3.email = '*****@*****.**'
    client3.password = '******'
    client3.is_active = True
    client3.is_email_verified = True
    client3.is_evidence_verified = True
    client3.evidence.first_name = 'FirstName3'
    client3.evidence.last_name = 'LastName3'
    client3.evidence.mobile_phone = '+111111111'
    client3.evidence.fixed_phone = '+222222222'
    client3.evidence.birthday = '2020-10-21'
    client3.evidence.address = 'Address3 - address3 - address3'
    client3.evidence.gender = 'male'
    client3.evidence.city = tehran_city
    client3.evidence.id_card = join(STUFF_DIR, 'test-image-1.jpg')
    client3.evidence.id_card_secondary = join(STUFF_DIR, 'test-image-2.png')
    DBSession.add(client3)

    DBSession.flush()

    # Markets
    tirr = Fiat(
        symbol='TIRR',
        name='Iran Rial',
        normalization_scale=-8,
        smallest_unit_scale=0
    )

    tbtc = Cryptocurrency(
        symbol='TBTC',
        name='Bitcoin',
        wallet_id="TBTC",
        normalization_scale=0,
        smallest_unit_scale=-8
    )
    teth = Cryptocurrency(
        symbol='TETH',
        name='Ethereum',
        wallet_id='TETH',
        normalization_scale=-1,
        smallest_unit_scale=-18
    )

    tirr_tbtc = Market(name='TIRR_TBTC', base_currency=tbtc, quote_currency=tirr)
    tirr_teth = Market(name='TIRR_TETH', base_currency=teth, quote_currency=tirr)
    tbtc_teth = Market(name='TBTC_TETH', base_currency=teth, quote_currency=tbtc)

    DBSession.add(tirr_tbtc)
    DBSession.add(tirr_teth)
    DBSession.add(tbtc_teth)

    # Payment Gateways
    shaparak = PaymentGateway()
    shaparak.name = "tshaparak"
    shaparak.fiat_symbol = "TIRR"
    shaparak.cashin_min = 10000,
    shaparak.cashin_max = 0,
    shaparak.cashin_static_commission = 0,
    shaparak.cashin_commission_rate = '0.0',
    shaparak.cashin_max_commission = 0,

    DBSession.add(shaparak)

    DBSession.flush()

    # Funds
    # DBSession.add(Fund(client=client1, currency=btc, total_balance=0, blocked_balance=0))
    # DBSession.add(Fund(client=client2, currency=btc, total_balance=34700000, blocked_balance=14660000))
    # DBSession.add(Fund(client=client3, currency=btc, total_balance=10000000000, blocked_balance=0))
    # DBSession.add(Fund(client=client1, currency=irr, total_balance=0, blocked_balance=0))
    # DBSession.add(Fund(client=client2, currency=irr, total_balance=56000000, blocked_balance=158000))
    # DBSession.add(Fund(client=client3, currency=irr, total_balance=9872000000, blocked_balance=150578))

    DBSession.flush()
Ejemplo n.º 16
0
    def mention(self):
        form = context.form
        mention = Mention()
        mention.body = form.get('body')

        origin_target = DBSession.query(Target) \
            .filter(Target.id == form.get('originTargetId')) \
            .one_or_none()
        if origin_target is None:
            raise HTTPTargetNotFound()

        mention.origin_target_id = origin_target.id

        if not (self.target or self.member):
            raise HTTPNotFound()

        if self.target:
            mention.target_id = self.target.id
            mention.sender_id = Member.current().id
            DBSession.add(mention)
            DBSession.flush()
            queues.push(settings.messaging.workers_queue, mention.to_dict())

        else:
            mentioner = Member.current()
            mentioned = self.member

            if mentioner.id == mentioned.id:
                raise HTTPStatus('620 Can Not Mention Yourself')

            aliased_target = aliased(Target)
            aliased_target_member1 = aliased(TargetMember)
            aliased_target_member2 = aliased(TargetMember)

            target_member = DBSession.query(aliased_target_member1) \
                .join(
                    aliased_target_member2,
                    aliased_target_member2.target_id == \
                    aliased_target_member1.target_id
                ) \
                .filter(aliased_target_member2.member_id == mentioner.id) \
                .filter(aliased_target_member1.member_id == mentioned.id) \
                .join(
                    aliased_target,
                    aliased_target.id == aliased_target_member1.target_id
                ) \
                .filter(aliased_target.type == 'direct') \
                .one_or_none()

            mention.sender_id = mentioner.id
            if target_member is None:
                direct = Direct(members=[mentioner, mentioned])
                DBSession.add(direct)
                DBSession.flush()
                mention.target_id = direct.id

            else:
                mention.target_id = target_member.target_id

            DBSession.add(mention)
            DBSession.flush()
            mention_message = mention.to_dict()
            mention_message.update({
                'mentionedMember': mentioned.id,
                'type': 'mention'
            })
            queues.push(settings.messaging.workers_queue, mention_message)
            webhook = Webhook()
            webhook.mentioned_member(mention.origin_target_id,
                                     mentioned.reference_id)

        return mention