Exemple #1
0
class DomainInfo(Document):
    Target = ReferenceField('Target', reverse_delete_rule=CASCADE)
    SubDomains = ListField()
    IsValid = BooleanField(default=True)
Exemple #2
0
class TgMessage(TelegramDocument):
    meta = {'collection': 'telegram_message'}
    file_types = [
        'audio',
        'sticker',
        'video',
        'animation',
        'photo',
        'document',
        'voice',
        'video_note',
    ]
    _file_id = None

    class Meta:
        original = Message

    message_id = LongField()

    chat = ReferenceField(TgChat)
    from_user = ReferenceField(TgUser)

    original_object = DictField()

    reactions = DictField()

    is_current_message = BooleanField(default=False)

    def __new__(cls, *args, **kwargs):
        first_arg = next(iter(args), None)
        if first_arg is not None and isinstance(first_arg, Message):
            chat = TgChat.objects(id=first_arg.chat.id).first()
            obj = cls.objects(message_id=first_arg.message_id,
                              chat=chat).first()
            if obj:
                obj.self_from_object(first_arg)
                return obj
        return super().__new__(cls)

    def __repr__(self):
        return f'{super().__repr__()} - {self.message_id}:{self.chat.id}'

    @property
    def file_ids(self) -> Generator[int, None, None]:
        if self._file_id is not None:
            yield from self._file_id
            return

        self._file_id = []
        message = self.original_object

        if not message:
            return

        for file_type in self.file_types:
            file = message.get(file_type, None)
            if isinstance(file, list):
                for file_dict in file:
                    self._file_id.append(file_dict['file_id'])
            elif isinstance(file, dict) and 'file_id' in file:
                self._file_id.append(file['file_id'])

        yield from self._file_id

    def is_any_type_of(self, *types: str) -> str or None:
        if isinstance(types, str):
            types = [types]

        for type in types:
            if self.original_object.get(type):
                return type

    def _get_file_for_image_search(self, bot: Bot) -> File or None:
        if (not bot and not self._bot) or self.is_any_type_of(
                'photo', 'sticker') is None:
            return
        self._bot = bot or self._bot
        file_id = next(iter(self.file_ids), None)

        if not file_id:
            return

        return self._bot.get_file(file_id=file_id)

    def find_similar(self, chat_id: int = None, bot: Bot = None) -> list:
        file = self._get_file_for_image_search(bot)
        if not file:
            return []
        try:
            filter = None
            if chat_id:
                filter = {'term': {'metadata.chat_id': chat_id}}

            return image_match_ses.search_image(file.file_path,
                                                pre_filter=filter)
        except (ConnectionError, NewConnectionError, NotFoundError):
            return []

    def get_self_image_match(self, bot: Bot = None) -> dict or None:
        results = self.find_similar(bot)

        for result in results:
            if result['dist'] == 0.0:
                return result

    def add_to_image_match(self, chat_id: int = None, bot: Bot = None):
        metadata = None
        if chat_id:
            metadata = {'chat_id': chat_id}
        file = self._get_file_for_image_search(bot)
        if not file:
            return
        try:
            image_match_ses.add_image(file.file_path, metadata=metadata)
        except (ConnectionError, NewConnectionError, NotFoundError):
            return
Exemple #3
0
class UserEmail(EmbeddedDocument):
    email = StringField()
    primary_email = BooleanField()
    verified = BooleanField()
Exemple #4
0
class Case(Document):
    """Represents a case (family) of individuals (samples)."""
    # This is a string with the id for the family:
    case_id = StringField(primary_key=True, required=True)
    # This is the string that will be shown in scout:
    display_name = StringField(required=True)
    # This is the owner of the case. E.g. 'cust003'
    owner = StringField(required=True)
    # These are the names of all the collaborators that are allowed to view the
    # case, including the owner
    collaborators = ListField(StringField())
    assignee = ReferenceField('User')
    individuals = ListField(EmbeddedDocumentField(Individual))
    created_at = DateTimeField(default=datetime.now)
    updated_at = DateTimeField(default=datetime.now)
    suspects = ListField(ReferenceField('Variant'))
    causative = ReferenceField('Variant')

    # The synopsis is a text blob
    synopsis = StringField(default='')
    status = StringField(default='inactive', choices=STATUS)
    is_research = BooleanField(default=False)

    # default_gene_lists specifies which gene lists that should be shown when
    # the case is opened
    default_gene_lists = ListField(StringField())
    clinical_gene_lists = ListField(EmbeddedDocumentField(GeneList))
    research_gene_lists = ListField(EmbeddedDocumentField(GeneList))
    dynamic_gene_list = ListField(DictField())

    genome_build = StringField()
    genome_version = FloatField()

    analysis_date = StringField()

    gender_check = StringField(choices=['unconfirmed', 'confirm', 'deviation'],
                               default='unconfirmed')
    phenotype_terms = ListField(EmbeddedDocumentField(PhenotypeTerm))
    # madeline info is a full xml file
    madeline_info = StringField()
    vcf_file = StringField()

    # The coverage report will be read as a binary blob
    coverage_report = BinaryField()

    @property
    def is_solved(self):
        """Check if the case is marked as solved."""
        return self.status == 'solved'

    @property
    def hpo_gene_ids(self):
        """Parse out all HGNC symbols form the dynamic Phenomizer query."""
        return [
            term['gene_id'] for term in self.dynamic_gene_list
            if term['gene_id']
        ]

    @property
    def bam_files(self):
        """Aggregate all BAM files across all individuals."""
        return [
            individual.bam_file for individual in self.individuals
            if individual.bam_file
        ]

    @property
    def all_gene_lists(self):
        """Yield all gene lists (both clinical and research)."""
        return itertools.chain(self.clinical_gene_lists,
                               self.research_gene_lists)

    def __repr__(self):
        return "Case(case_id={0}, display_name={1}, owner={2})".format(
            self.case_id, self.display_name, self.owner)
Exemple #5
0
class School(Document):
    code = IntField(required=True, primary_key=True)
    name = StringField(required=True)
    street = StringField(required=True)
    suburb = StringField(required=True)
    postcode = IntField(required=True)
    phone = StringField(required=True)
    email = EmailField(required=True)
    website = URLField(required=True)
    logo = URLField(required=False)
    fax = StringField(required=True)
    enrolments = IntField(required=True)
    level = StringField(required=True)
    opportunity_classes = BooleanField(requred=True)
    specialty_type = StringField(required=True)
    subtype = StringField(required=True)
    selective = StringField(required=True)
    gender = StringField(required=True)
    location = PointField(required=True)
    preschool = BooleanField(required=True)
    late_opening = BooleanField(required=True)
    intensive_english_centre = BooleanField(required=True)
    healthy_canteen = BooleanField(required=True)
    indigenous_pct = FloatField(required=True)
    lbote_pct = FloatField(required=True)
    icsea = IntField(required=True)
    support_classes = ListField(required=False)
    attendance_rate = FloatField(required=False)
    selective_entry_score = IntField(required=False)
    opportunity_classes_entry_score = IntField(required=False)
    train_station_id = StringField(required=False)
    train_station = StringField(required=False)
    train_distance = IntField(required=False)
    train_duration = IntField(required=False)
    meta = {'collection': 'schools'}

    def __init__(self, code, name, street, suburb, postcode, phone, email, website, fax, enrolments,
                 level, opportunity_classes, specialty_type, subtype, selective, gender, location, preschool,
                 late_opening, intensive_english_centre, healthy_canteen, indigenous_pct, lbote_pct, icsea,
                 *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.code = code
        self.name = name
        self.street = street
        self.suburb = suburb
        self.postcode = postcode
        self.phone = phone
        self.email = email
        self.website = website
        self.fax = fax
        self.enrolments = enrolments
        self.level = level
        self.opportunity_classes = opportunity_classes
        self.specialty_type = specialty_type
        self.subtype = subtype
        self.selective = selective
        self.gender = gender
        self.location = location
        self.preschool = preschool
        self.late_opening = late_opening
        self.intensive_english_centre = intensive_english_centre
        self.healthy_canteen = healthy_canteen
        self.indigenous_pct = indigenous_pct
        self.lbote_pct = lbote_pct
        self.icsea = icsea
Exemple #6
0
class FileContentUnit(ContentUnit):
    """
    A content unit representing content that is of type *file*.

    :ivar downloaded: Indicates whether all of the files associated with the
        unit have been downloaded.
    :type downloaded: bool
    """

    downloaded = BooleanField(default=True)

    meta = {
        'abstract': True,
        'indexes': [
            'downloaded'
        ]
    }

    @classmethod
    def pre_save_signal(cls, sender, document, **kwargs):
        """
        The signal that is triggered before a unit is saved.
        Ensures the _storage_path is populated.

        :param sender: sender class
        :type sender: object
        :param document: Document that sent the signal
        :type document: FileContentUnit
        """
        super(FileContentUnit, cls).pre_save_signal(sender, document, **kwargs)
        if not document._storage_path:
            document.set_storage_path()

    def set_storage_path(self, filename=None):
        """
        Set the storage path.
        This is a total hack to support existing single-file units with a
        _storage_path that includes the file name.

        :param filename: An optional filename to appended to the path.
        :rtype filename: str
        """
        path = FileStorage.get_path(self)
        if filename:
            if not os.path.isabs(filename):
                path = os.path.join(path, filename)
            else:
                raise ValueError(_('must be relative path'))
        self._storage_path = path

    def import_content(self, path, location=None):
        """
        Import a content file into platform storage.
        The (optional) *location* may be used to specify a path within the unit
        storage where the content is to be stored.
        For example:
          import_content('/tmp/file') will store 'file' at: _storage_path
          import_content('/tmp/file', 'a/b/c) will store 'file' at: _storage_path/a/b/c

        :param path: The absolute path to the file to be imported.
        :type path: str
        :param location: The (optional) location within the unit storage path
            where the content is to be stored.
        :type location: str

        :raises ImportError: if the unit has not been saved.
        :raises PulpCodedException: PLP0037 if *path* is not an existing file.
        """
        if not self._last_updated:
            raise ImportError("Content unit must be saved before associated content"
                              " files can be imported.")
        if not os.path.isfile(path):
            raise exceptions.PulpCodedException(error_code=error_codes.PLP0037, path=path)
        with FileStorage() as storage:
            storage.put(self, path, location)

    def save_and_import_content(self, path, location=None):
        """
        Saves this unit to the database, then calls safe_import_content.

        :param path: The absolute path to the file to be imported
        :type path: str
        :param location: The (optional) location within the unit storage path
            where the content is to be stored.
        :type location: str
        """
        self.save()
        self.safe_import_content(path, location)

    def safe_import_content(self, path, location=None):
        """
        If import_content raises exception, cleanup and raise the exception

        :param path: The absolute path to the file to be imported
        :type path: str
        :param location: The (optional) location within the unit storage path
            where the content is to be stored.
        :type location: str
        """
        try:
            self.import_content(path, location)
        except:
            self.clean_orphans()
            raise

    def clean_orphans(self):
        """
        Exposes the ability to clean up this unit as an orphan.
        """
        orphan_manger = factory.content_orphan_manager()
        orphan_manger.delete_orphan_content_units_by_type(self._content_type_id, self.id)
Exemple #7
0
class Session(Document):
    parent_id = StringField()
    name = StringField(required=True)
    guild = StringField(required=True)
    description = StringField()
    channel_id = StringField()
    character = ReferenceField(Character)
    characters = ListField(StringField())
    archived = BooleanField(default=False)
    history_id = StringField()
    started_on = DateTimeField()
    ended_on = DateTimeField()
    created_by = StringField()
    created = DateTimeField(required=True)
    updated_by = StringField()
    updated = DateTimeField(required=True)

    @classmethod
    def post_save(cls, sender, document, **kwargs):
        if document.history_id:
            user = User().get_by_id(document.updated_by)
            user.history_id = document.history_id
            user.updated_by = document.updated_by
            user.updated = document.updated
            user.save()
            print({'history_id': document.history_id})
        else:
            changes = document._delta()[0]
            action = 'updated'
            if 'created' in kwargs:
                action = 'created' if kwargs['created'] else action
            if action == 'updated' and 'archived' in changes:
                action = 'archived' if changes['archived'] else 'restored'
            Log().create_new(str(document.id), document.name,
                             document.updated_by, document.guild, 'Session',
                             changes, action)
            user = User().get_by_id(document.updated_by)
            if user.history_id:
                user.history_id = None
                user.updated_by = document.updated_by
                user.updated = document.updated
                user.save()
            print(changes)

    @staticmethod
    def query():
        return Session.objects

    @staticmethod
    def filter(**params):
        return Session.objects.filter(**params)

    def create_new(self, user, guild, channel_id, name, archived):
        self.name = name
        self.guild = guild
        self.channel_id = channel_id
        self.created_by = str(user.id)
        self.created = T.now()
        self.updated_by = str(user.id)
        self.updated = T.now()
        self.save()
        return self

    def find(self, guild, channel_id, name, archived=False):
        filter = Session.objects(guild=guild,
                                 channel_id=channel_id,
                                 name__icontains=name,
                                 archived=archived)
        session = filter.first()
        return session

    def get_or_create(self, user, guild, channel, name, archived=False):
        session = self.find(guild, str(channel.id), name, archived)
        if session is None:
            session = self.create_new(user, guild, str(channel.id), name,
                                      archived)
            session.character = Character().get_or_create(
                user, name, guild, session, 'Session', archived)
            session.save()
        return session

    def get_by_id(self, id):
        session = Session.objects(id=id).first()
        return session

    @classmethod
    def get_by_channel(cls, channel, archived=False, page_num=1, page_size=5):
        if page_num:
            offset = (page_num - 1) * page_size
            items = cls.filter(
                channel_id=str(channel.id),
                archived=archived).skip(offset).limit(page_size).all()
        else:
            items = cls.filter(channel_id=str(channel.id),
                               archived=archived).order_by('name',
                                                           'created').all()
        return items

    @classmethod
    def get_by_page(cls, params, page_num=1, page_size=5):
        if page_num:
            offset = (page_num - 1) * page_size
            logs = cls.filter(**params).order_by(
                'name', 'created').skip(offset).limit(page_size).all()
        else:
            logs = cls.filter(**params).order_by('name', 'created').all()
        return logs

    @classmethod
    def get_by_parent(cls, **params):
        items = cls.filter(**params).all()
        return [items] if items else []

    def archive(self, user):
        self.reverse_archive(self.user)
        self.archived = True
        self.updated_by = str(user.id)
        self.updated = T.now()
        self.save()

    def reverse_archive(self, user):
        for s in Session().get_by_parent(parent_id=str(self.id)):
            s.reverse_archive(self.user)
            s.archived = True
            s.updated_by = str(user.id)
            s.updated = T.now()
            s.save()

    def restore(self, user):
        self.reverse_restore(self.user)
        self.archived = False
        self.updated_by = str(user.id)
        self.updated = T.now()
        self.save()

    def reverse_restore(self, user):
        for s in Session().get_by_parent(parent_id=str(self.id)):
            s.reverse_restore(self.user)
            s.archived = False
            s.updated_by = str(user.id)
            s.updated = T.now()
            s.save()

    def get_string_characters(self, user=None):
        characters = '\n                '.join(
            f'***{c.name}***' + (' _(Active Character)_' if str(c.id) ==
                                 user.active_character else '')
            for c in Character.filter(
                id__in=[ObjectId(id) for id in self.characters]) if c)
        return f'\n\n            _Characters:_\n                {characters}'

    def get_string(self, channel=None, user=None):
        if user and not user.time_zone:
            raise Exception(
                'No time zone defined```css\n.d user timezone New_York```')
        name = f'***{self.name}***'
        active = ''
        if channel:
            active = ' _(Active Session)_ ' if str(
                self.id) == channel.active_session else ''
        start = ''
        if self.started_on:
            start = f'\n_Started On:_ ***{T.to(self.started_on, user)}***' if self.started_on else ''
        end = ''
        if self.ended_on:
            end = f'\n_Ended On:_ ***{T.to(self.ended_on, user)}***' if self.ended_on else ''
        description = f' - "{self.description}"' if self.description else ''
        characters = f'{self.get_string_characters(user)}' if self.characters else ''
        if self.character:
            name = f'***{self.character.name}***' if self.character.name else name
            description = f' - "{self.character.description}"' if self.character.description else description
        return f'        {name}{active}{start}{end}{description}{characters}'

    def get_short_string(self, channel=None):
        name = f'***{self.name}***'
        active = ''
        if channel:
            active = ' _(Active Session)_ ' if str(
                self.id) == channel.active_session else ''
        return f'        {name}{active}'
Exemple #8
0
class DPVP(Request):

    full_name = 'Devolución proporcional del valor pagado por concepto de derechos de matrícula'

    percentage = FloatField(required=True,
                            display='Porcentaje devuelto',
                            default=0.0)
    cancel = BooleanField(required=True,
                          display='¿Cancelación fue aprobada?',
                          default=True)
    council_number = StringField(required=True,
                                 max_length=2,
                                 default='00',
                                 display='# Acta de cancelación')
    council_year = StringField(required=True,
                               min_length=4,
                               max_length=4,
                               display='Año del Acta',
                               default='0000')

    regulation_list = ['032|2010|CSU', '1416|2013|RE']

    str_cm = [
        'devolución proporcional del {:0.2f} % del valor pagado por concepto de '
        +
        'derechos de matricula del periodo {}, teniendo en cuenta la fecha de '
        +
        'presentación de la solicitud y que {}le fue aprobada la cancelación '
        + 'de periodo en Acta {} de {} de Consejo de Facultad.'
    ]
    str_pcm = []

    def cm(self, docx):
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.str_council_header + ' ')
        self.cm_answer(paragraph)

    def cm_answer(self, paragraph):
        paragraph.add_run(
            # pylint: disable=no-member
            self.get_approval_status_display().upper() + ' ').font.bold = True
        self.add_text(paragraph)

    def pcm(self, docx):
        add_analysis_paragraph(docx, self.extra_analysis)
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.str_answer + ' ').font.bold = True
        paragraph.add_run(self.str_comittee_header + ' ')
        self.pcm_answer(paragraph)

    def pcm_answer(self, paragraph):
        paragraph.add_run(
            # pylint: disable=no-member
            self.get_advisor_response_display().upper() + ' ').font.bold = True
        self.add_text(paragraph)

    def add_text(self, paragraph):
        modifier = '' if self.cancel else 'no '
        paragraph.add_run(self.str_cm[0].format(self.percentage,
                                                self.academic_period, modifier,
                                                self.council_number,
                                                self.council_year))

    def resource_analysis(self, docx):
        last_paragraph = docx.paragraphs[-1]
        self.pcm_answer(last_paragraph)

    def resource_pre_answer(self, docx):
        last_paragraph = docx.paragraphs[-1]
        self.pcm_answer(last_paragraph)

    def resource_answer(self, docx):
        last_paragraph = docx.paragraphs[-1]
        self.cm_answer(last_paragraph)
Exemple #9
0
class FileContentUnit(ContentUnit):
    """
    A content unit representing content that is of type *file*.

    :ivar downloaded: Indicates whether all of the files associated with the
        unit have been downloaded.
    :type downloaded: bool
    """

    downloaded = BooleanField(default=True)

    meta = {'abstract': True, 'indexes': ['downloaded']}

    @classmethod
    def pre_save_signal(cls, sender, document, **kwargs):
        """
        The signal that is triggered before a unit is saved.
        Ensures the _storage_path is populated.

        :param sender: sender class
        :type sender: object
        :param document: Document that sent the signal
        :type document: FileContentUnit
        """
        super(FileContentUnit, cls).pre_save_signal(sender, document, **kwargs)
        if not document._storage_path:
            document.set_storage_path()

    def set_storage_path(self, filename=None):
        """
        Set the storage path.
        This is a total hack to support existing single-file units with a
        _storage_path that includes the file name.

        :param filename: An optional filename to appended to the path.
        :rtype filename: str
        """
        path = FileStorage.get_path(self)
        if filename:
            if not os.path.isabs(filename):
                path = os.path.join(path, filename)
            else:
                raise ValueError(_('must be relative path'))
        self._storage_path = path

    def list_files(self):
        """
        List absolute paths to files associated with this unit.
        This *must* be overridden by multi-file unit subclasses.

        :return: A list of absolute file paths.
        :rtype: list
        """
        if self._storage_path and not os.path.isdir(self._storage_path):
            return [self._storage_path]
        else:
            return []

    def import_content(self, path, location=None):
        """
        Import a content file into platform storage.
        The (optional) *location* may be used to specify a path within the unit
        storage where the content is to be stored.
        For example:
          import_content('/tmp/file') will store 'file' at: _storage_path
          import_content('/tmp/file', 'a/b/c) will store 'file' at: _storage_path/a/b/c

        :param path: The absolute path to the file to be imported.
        :type path: str
        :param location: The (optional) location within the unit storage path
            where the content is to be stored.
        :type location: str

        :raises PulpCodedException: PLP0036 if the unit has not been saved.
        :raises PulpCodedException: PLP0037 if *path* is not an existing file.
        """
        if not self._last_updated:
            raise exceptions.PulpCodedException(error_code=error_codes.PLP0036)
        if not os.path.isfile(path):
            raise exceptions.PulpCodedException(error_code=error_codes.PLP0037,
                                                path=path)
        with FileStorage() as storage:
            storage.put(self, path, location)
Exemple #10
0
class Comment(Document):
    _id = ObjectIdField()
    user = StringField(required=True)
    comment = StringField(required=True)
    is_thread = BooleanField(default=False),
    previous_comment = ObjectIdField()
Exemple #11
0
class EREP(Request):

    full_name = 'Expedición de recibo'

    ah_active = BooleanField(required=True,
                             display='¿Tiene activa la historia académica?',
                             default=False)
    payment_date = DateField(display='Fecha límite de pago')

    regulation_list = ['051|2003|CSU']  # List of regulations

    str_cm = [
        'presentar con concepto positivo al Comité de Matrículas de la Sede Bogotá, '
        +
        'la expedición de un único recibo correspondiente a los derechos académicos y '
        + 'administrativos para el periodo académico {}',
        ' y se le concede como fecha de ' +
        'pago el {} ({}), teniendo en cuenta el estado de pago por parte de {}.'
    ]

    list_analysis = ['El estudiante {}tiene la historia académica activa.']

    def cm(self, docx):
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.paragraph_format.space_after = Pt(0)
        self.cm_answer(paragraph)

    def cm_answer(self, paragraph):
        paragraph.add_run(self.str_council_header + ' ')
        paragraph.add_run(
            # pylint: disable=no-member
            self.get_approval_status_display().upper() + ' ').font.bold = True
        paragraph.add_run(self.str_cm[0].format(self.academic_period))
        if self.is_affirmative_response_approval_status():
            self.cm_af(paragraph)
        else:
            self.cm_ng(paragraph)

    def pcm(self, docx):
        self.pcm_analysis(docx)
        self.pcm_answer(docx)

    def pcm_answer(self, docx):
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.str_answer + ': ').font.bold = True
        paragraph.add_run(self.str_comittee_header + ' ')
        paragraph.add_run(
            # pylint: disable=no-member
            self.get_advisor_response_display().upper()).font.bold = True
        paragraph.add_run(' ' + self.str_cm[0].format(self.academic_period))
        if self.is_affirmative_response_advisor_response():
            self.pcm_answers_af(paragraph)
        else:
            self.pcm_answers_ng(paragraph)

    def cm_af(self, paragraph):
        paragraph.add_run(self.str_cm[1].format(
            self.payment_date, string_to_date(str(self.payment_date)),
            self.student_name))

    def cm_ng(self, paragraph):
        paragraph.add_run(self.council_decision + '.')

    def pcm_analysis(self, docx):
        active = '' if self.ah_active else 'no '
        final_analysis = []
        final_analysis += [self.list_analysis[0].format(active)]
        for extra_a in self.extra_analysis:
            final_analysis += [extra_a]
        add_analysis_paragraph(docx, final_analysis)

    def pcm_answers_af(self, paragraph):
        paragraph.add_run(self.str_cm[1].format(
            self.payment_date, string_to_date(str(self.payment_date)),
            self.student_name))

    def pcm_answers_ng(self, paragraph):
        paragraph.add_run(self.council_decision + '.')
Exemple #12
0
class User(UserMixin, db.Document):
    """
    用户模型 继承于数据库模型和 flask-login 的用户模型
    """
    uid = SequenceField()
    name = StringField(max_length=64, unique=True, required=True)
    email = StringField(max_length=64, unique=True, required=True)
    password_hash = StringField(max_length=128)
    confirmed = BooleanField(default=False)
    since = DateTimeField(default=datetime.utcnow())
    gender = BooleanField(default=True)
    interests = ListField(StringField(max_length=64))

    @property
    def password(self):
        """
        pasword 属性只有 setter 没有 getter
        :return: Error
        """
        raise AttributeError('password is not readable')

    @password.setter
    def password(self, password):
        """
        设置 password 散列值
        :param password: password
        :return: None
        """
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        """
        验证密码
        :param password: 输入的密码
        :return: bool
        """
        return check_password_hash(self.password_hash, password)

    def generate_confirmation_token(self, expiration=3600):
        """
        生成确认令牌 默认过期时间为1小时
        :param expiration: 过期时间
        :return: token
        """
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'confirm': str(self.id)})

    def confirm(self, token):
        """
        令牌确认,更改 confirmed 字段
        :param token: token
        :return: bool
        """
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except:
            return False
        if data.get('confirm') != str(self.id):
            return False
        self.confirmed = True
        self.save()
        return True

    def __repr__(self):
        return '<User %r>' % self.name
Exemple #13
0
class WebInfo(Document):
    # for whatweb cms
    Target = ReferenceField('Target', reverse_delete_rule=CASCADE)
    Data = DictField()
    IsValid = BooleanField(default=True)
Exemple #14
0
class HostInfo(Document):
    # for nmap
    Target = ReferenceField('Target', reverse_delete_rule=CASCADE)
    Ip = StringField()
    Data = DictField()
    IsValid = BooleanField(default=True)
Exemple #15
0
class User(Document, UserMixin):
    email = StringField(max_length=255)
    password = StringField(max_length=255)
    active = BooleanField(default=True)
    confirmed_at = DateTimeField()
    roles = ListField(ReferenceField(Role), default=[])
Exemple #16
0
class CRITsConfig(CritsDocument, Document):
    """
    CRITs Configuration Class.
    """

    from django.conf import settings

    meta = {
        "collection": settings.COL_CONFIG,
        "crits_type": 'Config',
        "latest_schema_version": 1,
        "schema_doc": {
        },
    }

    allowed_hosts = ListField(StringField(), default=['*'])
    classification = StringField(default='unclassified')
    company_name = StringField(default='My Company')
    create_unknown_user = BooleanField(default=False)
    crits_message = StringField(default='')
    crits_email = StringField(default='')
    crits_email_subject_tag = StringField(default='')
    crits_email_end_tag = BooleanField(default=True)
    # This is actually the internal DB version, but is named crits_version
    # for historical reasons.
    crits_version = StringField(required=True,
                                default=settings.CRITS_VERSION)
    debug = BooleanField(default=True)
    depth_max = IntField(default=10)
    email_host = StringField(default='')
    email_port = StringField(default='')
    enable_api = BooleanField(default=False)
    enable_toasts = BooleanField(default=False)
    git_repo_url = StringField(default='https://github.com/crits/crits')
    http_proxy = StringField(default='')
    instance_name = StringField(default='My Instance')
    instance_url = StringField(default='')
    invalid_login_attempts = IntField(default=3)
    language_code = StringField(default='en-us')
    ldap_auth = BooleanField(default=False)
    ldap_tls = BooleanField(default=False)
    ldap_server = StringField(default='')
    ldap_usercn = StringField(default='')
    ldap_userdn = StringField(default='')
    ldap_update_on_login = BooleanField(default=False)
    log_directory = StringField(default=os.path.join(settings.SITE_ROOT, '..', 'logs'))
    log_level = StringField(default='INFO')
    password_complexity_desc = StringField(default='8 characters, at least 1 capital, 1 lowercase and 1 number/special')
    password_complexity_regex = StringField(default='(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$')
    query_caching = BooleanField(default=False)
    rel_max = IntField(default=50)
    remote_user = BooleanField(default=False)
    rt_url = StringField(default='')
    secure_cookie = BooleanField(default=True)
    service_dirs = ListField(StringField())
    service_model = StringField(default='process')
    service_pool_size = IntField(default=12)
    session_timeout = IntField(default=12)
    splunk_search_url = StringField(default='')
    temp_dir = StringField(default='/tmp')
    timezone = StringField(default='America/New_York')
    total_max = IntField(default=250)
    totp_web = StringField(default='Disabled')
    totp_cli = StringField(default='Disabled')
    zip7_path = StringField(default='/usr/bin/7z')
    zip7_password = StringField(default='infected')

    def migrate(self):
        """
        Migrate the Configuration Schema to the latest version.
        """

        pass
Exemple #17
0
class User(YetiDocument):
    available_settings = dict()

    username = StringField(required=True, unique=True)
    password = StringField()
    enabled = BooleanField(required=True, default=True)
    permissions = DictField(verbose_name="Permissions")
    settings = DictField(verbose_name="Settings")
    api_key = StringField(required=True, unique=True)
    session_token = StringField()

    SEARCH_ALIASES = {}

    @property
    def is_authenticated(self):
        return self.enabled

    @property
    def is_admin(self):
        return self.permissions.get('admin', False)

    @property
    def is_active(self):
        return self.enabled

    @property
    def is_anonymous(self):
        return False

    def get_id(self):
        return unicode(self.session_token)

    def has_settings(self, settings):
        for setting in settings:
            if setting not in self.settings:
                return False
        return True

    def has_permission(self, object_name, permission):
        return self.permissions.get(object_name, {}).get(permission)

    def has_role(self, role):
        return self.permissions.get(role, False)

    def __unicode__(self):
        return u"<User: {}>".format(self.username)

    @classmethod
    def get_form(klass):
        return model_form(User)

    @classmethod
    def register_setting(klass, id, name, description):
        klass.available_settings[id] = {
            'name': name,
            'description': description
        }

    @classmethod
    def get_available_settings(klass):
        # We have to load all OneShotAnalytics in order to make sure
        # available_settings are up to date
        from core.analytics import OneShotAnalytics
        list(OneShotAnalytics.objects)

        return klass.available_settings

    @staticmethod
    def generate_api_key():
        return os.urandom(40).encode('hex')

    def info(self):
        i = {k: v for k, v in self._data.items() if k in ["username", "enabled", "permissions", "api_key"]}
        i['url'] = url_for("api.UserAdmin:post", id=str(self.id), _external=True)
        i['human_url'] = url_for("frontend.UsersView:profile", id=str(self.id), _external=True)
        return i
Exemple #18
0
class APGD(Request):
    class Coadvisor(EmbeddedDocument):
        name_co_advisor = StringField(display='Nombre del codirector',
                                      required=True,
                                      default='')
        inst_co_advisor = StringField(
            display='Departamento de adscripción del codirector',
            default=Request.DP_CIVIL_AGRICOLA,
            required=True,
            choices=Request.DP_CHOICES)
        co_advisor_ext = StringField(display='Institución externa', default='')

    full_name = 'Aprobación de propuesta de proyecto de tesis de maestria y ' +\
        'designación de director y co-director'

    GO_TRABAJO_FINAL_MAESTRIA = 'TFM'
    GO_TESIS_MAESTRIA = 'TSM'
    GO_TESIS_DOCTORADO = 'TSD'
    GO_CHOICES = ((GO_TRABAJO_FINAL_MAESTRIA, 'Trabajo Final de Maestría'),
                  (GO_TESIS_MAESTRIA, 'Tesis de Maestría'),
                  (GO_TESIS_DOCTORADO, 'Tesis de Doctorado'))

    IG_OWNERSHIP = 'OS'
    IG_NOT_OWNERSHIP = 'NO'
    IG_UNDEFINED = 'UN'
    IG_CHOICES = (
        (IG_OWNERSHIP, 'Sí pertenece'),
        (IG_NOT_OWNERSHIP, 'No pertenece'),
        (IG_UNDEFINED, 'No dice o no se sabe'),
    )

    CP_APROBADA = 'AP'
    CP_NO_APROBADO = 'NA'
    CP_CHOICES = (
        (CP_APROBADA, 'aprobado'),
        (CP_NO_APROBADO, 'no aprobado'),
    )

    grade_option = StringField(
        required=True,  # display='Tipo de tesis/trabajo final',
        choices=GO_CHOICES,
        default=GO_TESIS_MAESTRIA)
    enrolled_proyect = BooleanField(
        required=True,
        default=False,
        display='¿Tiene inscrita la asignatura proyecto de tesis?')
    have_signature = BooleanField(
        required=True,
        default=False,
        display='¿Tiene la firma del (los) director(es)?')
    enrroled_periods = IntField(min_value=1,
                                default=1,
                                display='Número de matrícula actual',
                                required=True)
    cd_delivered = BooleanField(required=True,
                                default=False,
                                display='¿Entregó CD?')
    general_objetive = StringField(required=True,
                                   display='Objetivo general',
                                   default='')
    specific_objetives = ListField(StringField(),
                                   display='Objetivos específicos')
    title = StringField(required=True,
                        display='Título de la tesis',
                        default='')
    ownership_ig = StringField(
        required=True,
        choices=IG_CHOICES,
        default=IG_UNDEFINED,
        display='¿El proyecto hace parte de un grupo de investigación?')
    advisor = StringField(display='Director de tesis',
                          default='',
                          required=True)
    advisor_inst = StringField(
        display='Departamento de adscripción del director',
        required=True,
        choices=Request.DP_CHOICES,
        default=Request.DP_EMPTY)
    advisor_ext = StringField(display='Institución externa', default='')
    co_advisor_list = EmbeddedDocumentListField(Coadvisor,
                                                display='Codirector(es)')
    grade_proyect = StringField(required=True,
                                display='Calificación del proyecto',
                                choices=CP_CHOICES,
                                default=CP_APROBADA)

    regulation_list = ['040|2017|CFA', '056|2012|CSU']  # List of regulations

    str_cm = [
        'Calificación {} ({}) a {} de {}, cuyo título es:',
        'Designar director', 'Designar codirector', 'al profesor', 'del',
        'de la institución', 'de', 'cuyo título es', 'Debido a que'
    ]

    list_analysis = [
        'Perfil de {}.', 'El estudiante {}tiene inscrita la asignatura {}.',
        'Estudiante de matrícula número {}.', 'ntregó CD.',
        'iene la firma del (los) director(es) de tesis/trabajo final:',
        'El proyecto de tesis debe inscribirse y entregarse, antes de alcanzar el 50'
        +
        '% de la duración establecida para el programa (Parágrafo Artículo 14 del '
        + '{})', 'Título:', 'Objetivo general:', 'Objetivos específicos:'
    ]

    def cm(self, docx):
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.str_council_header + ' ')
        self.cm_answer(paragraph)
        self.cm_grade(docx)
        if self.is_affirmative_response_approval_status():
            self.cm_design(docx)
        else:
            paragraph = docx.add_paragraph()
            paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
            paragraph.paragraph_format.space_after = Pt(0)
            paragraph.add_run(' ' + self.str_cm[8] + ' ' +
                              self.council_decision + '.')

    def cm_answer(self, paragraph):
        # pylint: disable=no-member
        paragraph.add_run(self.get_approval_status_display().upper() +
                          ':').font.bold = True

    def pcm(self, docx):
        self.pcm_analysis(docx)
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.str_answer + ': ').font.bold = True
        paragraph.add_run(self.str_comittee_header + ' ')
        self.pcm_answer(paragraph)
        self.cm_grade(docx)
        if self.is_affirmative_response_advisor_response():
            self.cm_design(docx)
        else:
            paragraph = docx.add_paragraph()
            paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
            paragraph.paragraph_format.space_after = Pt(0)
            paragraph.add_run(' ' + self.str_cm[8] + ' ' +
                              self.council_decision + '.')

    def pcm_answer(self, paragraph):
        # pylint: disable=no-member
        paragraph.add_run(self.get_advisor_response_display().upper() +
                          ':').font.bold = True

    def pcm_analysis(self, docx):
        # pylint: disable=no-member
        if self.grade_option in [
                self.GO_TESIS_MAESTRIA, self.GO_TESIS_DOCTORADO
        ]:
            profile = 'investigación'
        else:
            profile = 'profundización'
        type_subject = 'Proyecto' if self.grade_option in [
            self.GO_TESIS_MAESTRIA, self.GO_TESIS_DOCTORADO
        ] else 'Propuesta'
        final_analysis = []
        final_analysis += [self.list_analysis[0].format(profile)]
        ets = '' if self.enrolled_proyect else 'no '
        final_analysis += [
            self.list_analysis[1].format(
                ets, type_subject + ' ' + self.get_grade_option_display())
        ]
        final_analysis += [self.list_analysis[2].format(self.enrroled_periods)]
        cdd = 'E' if self.cd_delivered else 'No e'
        final_analysis += [cdd + self.list_analysis[3]]
        hss = 'T' if self.have_signature else 'No t'
        final_analysis += [
            hss + self.list_analysis[4] + ' ' + self.advisor + '.'
        ]
        final_analysis += [
            self.list_analysis[5].format(
                Request.regulations['056|2012|CSU'][0]) + '.'
        ]
        add_analysis_paragraph(docx, final_analysis)
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.style = 'List Bullet'
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.list_analysis[6] + ' ').font.bold = True
        paragraph.add_run(self.title + '.').font.italic = True
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.style = 'List Bullet'
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.list_analysis[7] + ' ').font.bold = True
        paragraph.add_run(self.general_objetive + '.')
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.style = 'List Bullet'
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.list_analysis[8]).font.bold = True
        for spec_ob in self.specific_objetives:
            paragraph = docx.add_paragraph()
            paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
            paragraph.style = 'List Bullet 2'
            paragraph.paragraph_format.space_after = Pt(0)
            paragraph.add_run(spec_ob + '.')
        for ex_an in self.extra_analysis:
            paragraph = docx.add_paragraph()
            paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
            paragraph.style = 'List Bullet'
            paragraph.paragraph_format.space_after = Pt(0)
            paragraph.add_run(ex_an + '.')

    def cm_grade(self, docx):
        # pylint: disable=no-member
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.style = 'List Bullet'
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.str_cm[0].format(
            self.grade_proyect, self.get_grade_proyect_display(),
            self.get_grade_option_display(),
            self.get_academic_program_display()))
        paragraph.add_run(' "{}".'.format(self.title)).font.italic = True

    def cm_design(self, docx):
        # pylint: disable=no-member
        paragraph = docx.add_paragraph()
        paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
        paragraph.style = 'List Bullet'
        paragraph.paragraph_format.space_after = Pt(0)
        paragraph.add_run(self.str_cm[1] + ' ')
        paragraph.add_run(self.str_cm[6] + ' ' +
                          self.get_grade_option_display() + ' ' +
                          self.str_cm[7])
        paragraph.add_run(' "{}" '.format(self.title)).font.italic = True
        paragraph.add_run(self.str_cm[3] + ' ')
        paragraph.add_run(self.advisor)
        if self.advisor_inst == Request.DP_EXTERNO_FACULTAD:
            paragraph.add_run(' ' + self.str_cm[5] + ' ' + self.advisor_ext +
                              '.')
        else:
            paragraph.add_run(' ' + self.str_cm[4] + ' ' +
                              self.get_advisor_inst_display() + '.')
        if self.co_advisor_list != []:
            for co_advc in self.co_advisor_list:
                paragraph = docx.add_paragraph()
                paragraph.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
                paragraph.style = 'List Bullet'
                paragraph.paragraph_format.space_after = Pt(0)
                paragraph.add_run(self.str_cm[2] + ' ')
                paragraph.add_run(self.str_cm[6] + ' ' +
                                  self.get_grade_option_display() + ' ' +
                                  self.str_cm[7])
                paragraph.add_run(' "{}" '.format(
                    self.title)).font.italic = True
                paragraph.add_run(self.str_cm[3] + ' ')
                paragraph.add_run(co_advc.name_co_advisor)
                if co_advc.inst_co_advisor == Request.DP_EXTERNO_FACULTAD:
                    paragraph.add_run(' ' + self.str_cm[5] + ' ' +
                                      co_advc.co_advisor_ext + '.')
                else:
                    paragraph.add_run(' ' + self.str_cm[4] + ' ' +
                                      co_advc.get_inst_co_advisor_display() +
                                      '.')

    def resource_analysis(self, docx):
        last_paragraph = docx.paragraphs[-1]
        self.pcm_answer(last_paragraph)

    def resource_pre_answer(self, docx):
        last_paragraph = docx.paragraphs[-1]
        self.pcm_answer(last_paragraph)

    def resource_answer(self, docx):
        last_paragraph = docx.paragraphs[-1]
        self.cm_answer(last_paragraph)
Exemple #19
0
class Transaction(DynamicDocument):
    created_at = DateTimeField(default=datetime.datetime.now)
    tag = StringField()
    channel = StringField(choices=ChannelNameChoices.choices)

    decision = ReferenceField(DecisionSignal)
    pair = StringField(choices=pairs_without_slash, required=True)
    take_profits = ListField(EmbeddedDocumentField('TakeProfit'))
    stop_loss = EmbeddedDocumentField('StopLoss')

    initial_pair_price = DecimalField(precision=6)
    initial_pair_price_retries = IntField()

    amount_invested = IntField()
    result = DecimalField(precision=6)
    result_ratio = FloatField()

    date_open = DateTimeField()
    date_closed = DateTimeField()
    status = StringField(choices=TransactionStatusChoices.choices)
    closed_by = StringField(choices=TransactionClosedByChoices.choices)
    duration = FloatField(default=None)

    is_ratio_suspicious = BooleanField(default=None)
    strategy_label = StringField()

    @property
    def profit_result(self):
        result = 0
        return result

    @property
    def history(self):
        return

    def assign_take_profits_from_strategy(self, assigned_amount, strategy, tp_closed_dates):
        take_profits_length = len(self.decision.take_profits)
        distribution = strategy.get(take_profits_length)
        if distribution is None:
            logger.error("add some extra distribution")

        take_profits = []
        if len(self.decision.take_profits) != len(tp_closed_dates):
            raise Exception("Incompatiblity")

        for tp, closed_date in zip(self.decision.take_profits, tp_closed_dates.values()):
            if closed_date == PositionCloseDetector.NOT_FOUND:
                closed_date = None

            try:
                distribution_percentage = distribution[tp['order_number']]
            except KeyError:
                if len(self.decision.take_profits) == 1:
                    distribution_percentage = 1
                    tp['order_number'] = 1
                else:
                    distribution_percentage = 0

            if distribution_percentage != 0:

                if list(distribution.values()).count(1) == 1:
                    tp['is_last'] = True

                take_profit = TakeProfit(
                    **tp,
                    closed_date=closed_date,
                    amount_invested=assigned_amount*distribution_percentage
                )

                take_profits.append(take_profit)

        try:
            if take_profits[-1]['is_last'] == False:
                logger.error('incorrect situation')
                take_profits[-1]['is_last'] = True
        except Exception:
            logger.error('Jaki exception ląduje?')

        return take_profits

    def get_event_id_cancel(self):
        return "{transaction_id}_cancel".format(transaction_id=self.id)


    def get_stop_loss_result(self):
        """
        There can be situation that stop loss has been triggered after 1 from 3 realised take_profits
        so in this case we realise StopLoss with 66% of invested money
        If 2 of 3 take profits are realised then we return 1/3*stop_loss.amount_invested
        """
        not_realised_take_profits = [tp for tp in self.take_profits
                                     if tp.is_closed is False]
        result = sum([tp.amount_invested for tp in not_realised_take_profits])
        return result

    def get_last_occured_event(self):
        take_profits_dates = {
            tp['order_number']: tp['closed_date']
            for tp in self.take_profits
            if tp['closed_date'] is not None
        }
        if self.stop_loss['closed_date'] != None:
            stop_loss_date = {'sl': self.stop_loss['closed_date']}
        else:
            stop_loss_date = {}

        zbior = {
            **take_profits_dates,
            **stop_loss_date
        }
        zbior_sorted = sorted(zbior.items(), key=lambda d: d[1], reverse=True)
        last_event = zbior_sorted[0]
        if last_event[0] == 'sl':
            return 'sl'
        elif isinstance(last_event[0], int):
            return 'tp'
        else:
            logger.error(f'LastEvent value error: {last_event[0]}')

    def on_last_take_profit_or_stop_loss_reached(self, closed_by, date_closed=None, duration=None):
        self.status = TransactionStatusChoices.CLOSED
        self.date_closed = date_closed
        self.closed_by = closed_by
        self.result = self.get_result()
        self.result_ratio = self.result/self.amount_invested
        self.duration = duration

        if self.is_result_suspicious():
            self.is_ratio_suspicious = True
            self.result = self.amount_invested
        else:
            self.is_ratio_suspicious = False

        self.save()

    def on_initial_price_not_found(self):
        self.status = TransactionStatusChoices.INITIAL_PRICE_NOT_FOUND
        self.save()

    def get_closed_take_profits_result(self):
        result = 0
        for tp in self.take_profits:
            if tp.is_closed:
                if tp.result is not None:
                    result += tp.result
                else: # is closed without result ? some error....
                    result += tp.amount_invested
        return result

    def get_result(self):
        if self.closed_by == TransactionClosedByChoices.TAKE_PROFIT:
            try:
                return self.get_closed_take_profits_result()
            except TypeError:
                take_profit_result = 0
                pass
        elif self.closed_by == TransactionClosedByChoices.STOP_LOSS:
            closed_take_profits_result = self.get_closed_take_profits_result()
            return closed_take_profits_result+(self.amount_invested-closed_take_profits_result)*self.stop_loss.ratio
        else:
            return self.amount_invested

    def is_result_suspicious(self):
        return self.result_ratio < 0.9 or self.result_ratio > 1.1 or \
               (self.closed_by == 'take_profit' and self.result < self.amount_invested) or \
               (self.closed_by =='stop_loss' and self.result > self.amount_invested)

    def cancel_all(self):
        for take_profit in self.decision.take_profits:
            take_profit.cancel()

    def cancel_particular(self, take_profit):
        take_profit.cancel()
        pass

    def add_hold_days(self, days):
        self.duration += days

    def change_stop_loss(self):
        pass

    def change_take_profit(self, take_profit):
        pass

    def add_take_profit(self, take_profit):
        pass
Exemple #20
0
class Message(Document):
    msg = StringField()
    sender = ObjectIdField()
    reciever = ObjectIdField()
    isRead = BooleanField(default=False)
    createdAt = DateTimeField(default=datetime.now())
Exemple #21
0
class User(Document, UserMixin):
    public_id = StringField(default=str(uuid.uuid4()))
    name = StringField()
    username = StringField(required=True, unique=True)
    password_hash = StringField()
    roles = ListField(default=[])
    active = BooleanField(default=True)

    def __init__(self, *args, **kwargs):
        if "password" in kwargs and kwargs.get("password") is not None:
            kwargs["password_hash"] = generate_password_hash(
                kwargs.pop("password"), method='sha256')
        # if "roles" in kwargs:
        #     roles = kwargs.pop("roles")
        #     o_roles = []
        #     if isinstance(roles, str):
        #         roles = roles.split(",")

        #     for role in roles:
        #         if isinstance(role, str):
        #             o_role = Role.objects(name=role).first()
        #             if o_role:
        #                 o_roles.append(o_role)
        #         elif isinstance(role, Role):
        #             o_roles.append(role)
        #     kwargs["roles"] = o_roles
        if kwargs.pop("admin", False):
            # o_admin = Role.objects(name__iexact="admin").first()
            # kwargs["roles"] = kwargs.get("roles",[]).append(o_admin)
            kwargs["roles"] = kwargs.get("roles", []) + ["admin"]
        super().__init__(*args, **kwargs)

    def to_barn_dict(self):
        return dict(name=self.name,
                    username=self.username,
                    public_id=self.public_id,
                    type="user",
                    active=self.active,
                    roles=self.roles)

    def reset_password(self, password):
        self.password_hash = generate_password_hash(password, method='sha256')

    def __repr__(self):
        return '<User %r>' % (self.name)

    def get_id(self):
        return self.public_id

    def has_role(self, role):
        return role in self.roles

    def get_roles(self):
        return [RoleNeed(**{'value': role}) for role in self.roles]

    def isadmin(self):
        if self.roles is not None and "admin" in self.roles:
            return True
        return False

    def missing_roles(self, roles):
        missing_roles = []

        if self.isadmin():
            return []
        for role in roles:
            if not self.has_role(role):
                missing_roles.append(role)
        return missing_roles

    def __hash__(self):
        return hash((self.name, self.username, self.public_id,
                     self.password_hash, self.active, frozenset(self.roles)))
Exemple #22
0
class SignatureAccess(EmbeddedDocument, CritsDocumentFormatter, CommonAccess):
    """
    ACL for Signatures.
    """

    upload_new_version = BooleanField(default=False)

    data_type_read = BooleanField(default=False)
    data_type_edit = BooleanField(default=False)

    data_type_min_version_read = BooleanField(default=False)
    data_type_min_version_edit = BooleanField(default=False)

    data_type_max_version_read = BooleanField(default=False)
    data_type_max_version_edit = BooleanField(default=False)

    data_read = BooleanField(default=False)
    data_edit = BooleanField(default=False)

    dependencies_read = BooleanField(default=False)
    dependencies_edit = BooleanField(default=False)
Exemple #23
0
class Link(Document):
    """Collection representing a shortened url"""

    long_url_index_spec = [('long_url', 'hashed')]

    meta = {
        'auto_create_index': settings.MONGO_AUTO_CREATE_INDEXES,
        # We can't used a "hashed" index on hash because it needs to be unique
        'indexes': [('hash', ), long_url_index_spec]
    }

    hash = StringField(required=True, unique=True)
    long_url = StringField(required=True)
    act_as_proxy = BooleanField()
    clicks = IntField(default=0)

    @classmethod
    def find_for_prefix(cls, prefix):
        """Retrieves all Link objects where the hash starts with a specific prefix
           If you do not give a prefix (or prefix='') this is not going to be indexed,
           so make sure you filter on another field that is actually indexed.
        """
        if prefix:
            return cls.objects(hash__startswith=('%s/' % prefix.lower()))
        else:
            return cls.objects(hash__not__contains='/')

    @classmethod
    def find_for_prefix_and_long_url(cls, prefix, long_url):
        """Retrieves Link objects for a specific long_url that also match a specific prefix"""
        # For some reason, we need to hint explictly at the index to use
        return cls.find_for_prefix(prefix).filter(long_url=long_url).hint(
            cls.long_url_index_spec)

    @classmethod
    def shorten(cls, long_url, short_path=None, prefix=None):
        """Public API to create a short link"""

        ForbiddenKeyword.raise_if_banned(short_path)
        ForbiddenKeyword.raise_if_banned(prefix)

        if prefix is None:
            prefix = ''

        if short_path is None or not len(short_path):
            link = cls.find_for_prefix_and_long_url(prefix, long_url).first()

            if link is None:
                link = cls.create_with_random_short_path(long_url, prefix)
        else:
            link, created = cls.__get_or_create(prefix, short_path, long_url)

            if not created and link.long_url != long_url:
                raise ShortPathConflict(link)

        link.save()

        return link

    @classmethod
    def create_with_random_short_path(cls, long_url, prefix):
        """Generate an unused, valid random short path for prefix"""
        nb_tries = 0

        while True:
            # Generate a seed from the long url and the current date (with milliseconds)
            seed = "%s%s%s" % (long_url, datetime.utcnow(), nb_tries)
            hashed = int(sha1(seed).hexdigest(), 16)
            mod = 1

            while hashed > mod:
                mod *= 10
                nb_tries += 1
                short_path = int_to_alnum.encode(hashed % mod)

                if not cls.is_valid_random_short_path(short_path):
                    continue

                link, created = cls.__get_or_create(prefix, short_path,
                                                    long_url)

                if created:
                    # Short path didn't exist, store number of tries and we're done
                    statsd.histogram('workforus.nb_tries_to_generate',
                                     nb_tries,
                                     tags=['prefix:' + prefix])
                    return link

    RE_VALID_RANDOM_SHORT_PATHS = re.compile(r'^([a-z]{0,2}\d)+[a-z]{0,2}$')

    @classmethod
    def is_valid_random_short_path(cls, short_path):
        """Checks if the random short path is valid (does not contain words)"""
        # We don't check for ForbiddenKeywords because the constraints make that redundant
        return cls.RE_VALID_RANDOM_SHORT_PATHS.match(short_path) is not None

    @classmethod
    def __get_or_create(cls, prefix, short_path, long_url):
        """Retrieves or Creates a Link object by (prefix, short_path)"""
        # pylint: disable=W0511
        # FIXME: Deprecated in MongoEngine 0.8 - https://work4labs.atlassian.net/browse/OPS-1529
        return cls.objects.get_or_create(
            hash=Link.hash_for_prefix_and_short_path(prefix, short_path),
            defaults={'long_url': long_url})

    @classmethod
    def hash_for_prefix_and_short_path(cls, prefix, short_path):
        """Returns the hash for a combination of prefix and short_path"""
        return ('%s%s' %
                ('%s/' % prefix if prefix != '' else '', short_path)).lower()

    @classmethod
    def find_by_hash(cls, path):
        """Searches for a Link object by hash"""
        return cls.objects(hash=path.lower()).first()

    @property
    def prefix(self):
        """If present, return the prefix"""
        if '/' not in self.hash:
            return ''

        return self.hash.split('/')[0]

    def click(self):
        """Register a click on this link"""
        self.__class__.objects(hash=self.hash).update_one(inc__clicks=1)

    def build_relative_path(self):
        """Builds the relative path for the current url (since we only store the hash, we get a lowercase version)"""
        return '/%s' % self.hash

    def build_absolute_uri(self, request):
        """Builds the absolute url for the target link (including full server url)"""
        return request.build_absolute_uri(self.build_relative_path())

    def __str__(self):
        return "%s -> %s\n" % (self.hash, self.long_url)
Exemple #24
0
class User(Document):
    meta = {"collection": "Users", 'allow_inheritance': True}
    first_name = StringField(required=True)
    last_name = StringField(required=True)
    username = StringField(required=True)
    moderator = BooleanField(required=True, default=False)
    locale = 'en_GB'
    points = IntField(required=True, default=0)
    cursors = DictField()
    has_read_welcome_msg = BooleanField(required=True, default=False)
    has_paid = BooleanField(required=True, default=False)
    payment_details = EmbeddedDocumentField(UserPaymentDetails)
    price = StringField(required=True, default="4.99")

    def record_payment(self, transaction_id, receipt_id):
        '''
        Records the payment
        '''
        self.has_paid = True
        pd = UserPaymentDetails()
        pd.transaction_id = transaction_id
        pd.receipt_id = receipt_id
        self.payment_details = pd
        self.save()

    def toggle_moderator(self):
        self.moderator = not self.moderator
        self.save()

    def update_section_cursor(self, section_id, section_length,
                              current_cursor):
        self.cursors.setdefault(section_id, 0)

        #Only increment cursor if this is an unseen nugget and we havent' finished studying the section
        if current_cursor >= self.cursors[
                section_id] and current_cursor + 1 < section_length:
            self.cursors[section_id] += 1
            self.save()

    def get_section_cursor(self, section_id):
        #Get either the first nugget of the section or where the user left it off.
        return self.cursors.has_key(
            section_id) and self.cursors[section_id] or 0

    def update_points(self, score):
        self.points += score * 10
        self.save()

    def get_user_stats(self):
        '''
        calculates user stats and returns a dict.
        '''
        try:
            stats = {}
            test_history = Test.objects(user=str(self.id))
            if len(test_history) != 0:
                no_of_correct_answers = 0
                for test in test_history:
                    no_of_correct_answers += test.score

                stats['correct_answers'] = no_of_correct_answers

                #count total questions
                total_questions_answered = 0
                for test in test_history:
                    if isinstance(test, MockTest):
                        total_questions_answered += 50
                    elif isinstance(test, PractiseTest):
                        total_questions_answered += 20

                stats['accuracy'] = 0
                if total_questions_answered != 0:
                    stats['accuracy'] = 100 * no_of_correct_answers / float(
                        total_questions_answered)

                stats['total_questions_answered'] = total_questions_answered
            else:
                stats['correct_answers'] = 0
                stats['accuracy'] = 0
                stats['total_questions_answered'] = 0

            stats[
                'points'] = self.points  #The user may receive points without completing a test. We're good people

            return stats
        except Exception, e:
            print e
Exemple #25
0
class SessionConfigs(Document):
    sesssionExpirationTime = LongField(required=True, default=60)
    carryOverSlots = BooleanField(required=True, default=True)
    bot = StringField(required=True)
    user = StringField(required=True)
    timestamp = DateTimeField(default=datetime.utcnow)
class Roles(EmbeddedDocument):
    """
    Roles Permission
    """
    admin: BooleanField = BooleanField(default=False)
 class Book(Document):
     name = StringField()
     pages = IntField()
     tags = ListField(StringField())
     is_published = BooleanField()
     author_email = EmailField()
Exemple #28
0
class Domain(CritsBaseAttributes, CritsSourceDocument, Document):
    """
    Domain Class.
    """

    meta = {
        "collection": settings.COL_DOMAINS,
        "crits_type": 'Domain',
        "latest_schema_version": 2,
        "schema_doc": {
            'analyst': 'Analyst who added/modified this domain',
            'domain': 'The domain name of this domain',
            'type': 'Record type of this domain',
            'watchlistEnabled': 'Boolean - whether this is a domain to watch',
            'whois': 'List [] of dictionaries of whois data on given dates',
        },
        "jtable_opts": {
                         'details_url': 'crits.domains.views.domain_detail',
                         'details_url_key': 'domain',
                         'default_sort': "domain ASC",
                         'searchurl': 'crits.domains.views.domains_listing',
                         'fields': [ "domain", "modified", "source",
                                     "campaign", "status", "id"],
                         'jtopts_fields': [ "details",
                                            "domain",
                                            "modified",
                                            "source",
                                            "campaign",
                                            "status",
                                            "favorite",
                                            "id"],
                         'hidden_fields': [],
                         'linked_fields': ["source", "campaign"],
                         'details_link': 'details',
                         'no_sort': ['details']
                       }

    }

    domain = StringField(required=True)
    record_type = StringField(default="A", db_field="type")
    watchlistEnabled = BooleanField(default=False)
    whois = ListField(EmbeddedDocumentField(EmbeddedWhoIs))
    analyst = StringField()

    def migrate(self):
        """
        Migrate to the latest schema version.
        """

        migrate_domain(self)

    def _custom_save(self, force_insert=False, validate=True, clean=False,
        write_concern=None, cascade=None, cascade_kwargs=None,
        _refs=None, username=None, **kwargs):
        """
        Custom save. Overrides default core custom save function.
        """

        #TODO: parse for potential root domain and add it as well?
        # - would require adding relationships between the two as well
        return super(self.__class__, self)._custom_save(force_insert, validate,
            clean, write_concern, cascade, cascade_kwargs, _refs, username)

    def add_whois(self, data, analyst, date=None, editable=True):
        """
        Add whois information to the domain.

        :param data: The contents of the whois.
        :type data: str
        :param analyst: The user adding the whois.
        :type analyst: str
        :param date: The date for this whois entry.
        :type date: datetime.datetime
        :param editable: If this entry can be modified.
        :type editable: boolean
        :returns: :class:`crits.core.domains.domain.WhoisEntry`
        """

        if not date:
            date = datetime.datetime.now()
        whois_entry = WhoisEntry(data).to_dict()

        e = EmbeddedWhoIs()
        e.date = date
        e.analyst = analyst
        e.editable = editable
        e.text = data
        e.data = whois_entry
        self.whois.append(e)
        return whois_entry

    def edit_whois(self, data, date=None):
        """
        Edit whois information for the domain.

        :param data: The contents of the whois.
        :type data: str
        :param date: The date for this whois entry.
        :type date: datetime.datetime
        """

        if not date:
            return

        for w in self.whois:
            if w.date == date:
                whois_entry = WhoisEntry(data).to_dict()
                w.data = whois_entry
                w.text = data

    def delete_whois(self, date):
        """
        Remove whois information from the domain.

        :param date: The date for this whois entry.
        :type date: datetime.datetime
        """

        if not date:
            return

        for w in self.whois:
            if w.date == date:
                self.whois.remove(w)
                break

    def whois_diff(self, from_date, to_date):
        """
        Generate a diff between two whois entries.

        :param from_date: The date for the first whois entry.
        :type date: datetime.datetime
        :param to_date: The date for the second whois entry.
        :type date: datetime.datetime
        :returns: str, None
        """

        from_whois = None
        to_whois = None
        for w in self.whois:
            if w.date == from_date:
                from_whois = str(WhoisEntry.from_dict(w.data)).splitlines(True)
            if w.date == to_date:
                to_whois = str(WhoisEntry.from_dict(w.data)).splitlines(True)
        if not from_whois or not to_whois:
            return None
        return unified_diff(from_whois,
                            to_whois,
                            fromfile=from_date,
                            tofile=to_date)

    def to_cybox_observable(self):
        """
            Convert a Domain to a CybOX Observables.
            Returns a tuple of (CybOX object, releasability list).

            To get the cybox object as xml or json, call to_xml() or
            to_json(), respectively, on the resulting CybOX object.
        """
        obj = DomainName()
        obj.value = self.domain
        obj.type_ = self.record_type
        return ([Observable(obj)], self.releasability)

    @classmethod
    def from_cybox(cls, cybox_obs):
        """
        Convert a Cybox DefinedObject to a MongoEngine Domain object.

        :param cybox_obs: The cybox observable to create the Domain from.
        :type cybox_obs: :class:`cybox.core.Observable``
        :returns: :class:`crits.domains.domain.Domain`
        """
        cybox_object = cybox_obs.object_.properties
        db_obj = Domain.objects(domain=str(cybox_object.value)).first()
        if db_obj:
            return db_obj
        else:
            domain = cls()
            domain.domain = str(cybox_object.value)
            domain.record_type = str(cybox_object.type_)
            return domain
Exemple #29
0
class User(DynamicDocument):
    email = StringField(max_length=255, api_public=True)
    password = StringField(max_length=255)
    first_name = StringField( api_public=True)
    last_name = StringField( api_public=True)
    phone_number = StringField(max_length=255, api_public=True)
    role = StringField(default='owner', api_public=True)
    date_account_claimed = DateTimeField(api_public=True)
    date_last_invite_sent = DateTimeField(api_public=True)
    accepted_tos_date = DateTimeField()
    accepted_tos_ip = StringField()
    websocket_session_id = StringField()
    trading_account_username = StringField()
    trading_account_token = StringField()
    confirmed_emails = ListField(StringField(), default=[], api_public=True)
    authy_id = StringField() 
    enable_sound_alerts = BooleanField(default=False)
    enable_voice_alerts = BooleanField(default=False)

    def check_alerts(self):
        alerts = Alert.objects(user=self, is_open=True)
        for alert in alerts:
            alert.check()

    def check_trading_data(self):
        t = TradingService(token=self.trading_account_token)
        status = t.check()
        return status

    def clear_trading_account(self):
        self.trading_account_token = None
        self.trading_account_username = None
        self.save()

    def clear_positions(self):
        for position in Position.objects(is_open=True, user=self):
            position.remove()

    def stop_trading_data(self, token=None):
        token = token or self.trading_account_token
        t = TradingService(token=token)
        status = t.stop()
        self.clear_trading_account()
        self.clear_positions()
        return status

    def start_trading_data(self, username, password, trading_mode):
        self.stop_trading_data()
        websocket_endpoint = WEBSOCKET_ENDPOINT
        webhook_url = API_ENDPOINT + '/webhooks/trading_service'
        t = TradingService(
          username, password, trading_mode, 
          websocket_endpoint=websocket_endpoint, 
          startup_done_webhook=webhook_url,
        )
        token, status = t.start()
        self.logger.info('STARTING')
        self.logger.info(token)
        self.logger.info(status)
        self.trading_account_token = token
        self.trading_account_username = username
        self.save()
        return status

    def send_confirm_email(self):
        link = self.confirm_email_link()
        subject = "Please confirm your email"
        message_data = {
            'link': link, 
            'subject': subject,
        }
        self.send_message('confirm_email', 
            message_data=message_data)

    def has_role(self, role_name):
        return role_name == self.role

    @staticmethod 
    def hash_password(plaintext):
        plaintext = plaintext.encode('utf-8')
        hashed = bcrypt.hashpw(plaintext, bcrypt.gensalt()).decode('utf-8')
        return hashed

    @staticmethod
    def is_email_available(email, user):
        if user:
            existing_user = User.objects(email=email, id__ne=user.id).first() 
        else:
            existing_user = User.objects(email=email).first() 
        if not existing_user:
            return True
        return False

    @staticmethod
    def is_email_valid(email):
        return validate_email(email)

    @staticmethod
    def is_email_usable(email, user=None):
        email = email.lower().strip()
        if not User.is_email_available(email, user):
            return False, 'Email is in use'
        if not User.is_email_valid(email):
            return False, 'Email is invalid'
        return True, None

    def is_correct_password(self, plaintext):
        plaintext = plaintext.encode('utf-8')
        hashed_password = self.password.encode('utf-8')
        return bcrypt.checkpw(plaintext, hashed_password) 

    def set_password(self, password):
        self.password = User.hash_password(password)
        self.save()

    def set_email(self, email):
        email = email.lower().strip()
        self.email = email
        self.save()

    def set_phone_number(self, phone_number):
        self.phone_number = phone_number
        self.save()
        self.create_authy()

    def password_changed(self):
        """tell user their password has changed"""
        message_data = {'subject': 'Your password has changed'}
        self.send_message(message_template='password_changed', message_data=message_data)

    def password_reset_link(self, invite=False):
        """generate password reset link"""
        token = self.generate_token()
        link = self.dashboard_url() + CHANGE_PASSWORD_ROUTE + '?token=' + token
        if invite:
            link += '&invite=true'
        return link

    def confirm_email_link(self):
        """generate confirm email link and return"""
        token = self.generate_token()
        link = self.dashboard_url() + '/confirm_email?token=' + token 
        return link

    def send_invite(self, medium='email', message_template='invite_team', **data):
        """send invite link and send to user"""
        link = self.password_reset_link(invite=True)
        subject = "You've been invited to {}".format(BRAND_NAME)
        message_data = {
            'link': link, 
            'subject': subject,
        }
        message_data.update(data)
        self.send_message(message_template=message_template, 
            message_data=message_data, medium=medium)
        self.date_last_invite_sent = datetime.datetime.now()
        self.save()

    def claim_account(self): 
        if not self.date_account_claimed:
            self.date_account_claimed = datetime.datetime.now()
            self.save()

    def dashboard_url(self):
        """get the dashboard url if this user"""
        url = DASHBOARD_ENDPOINT
        return url

    def send_password_reset(self):
        """generate password token and send to user"""
        link = self.password_reset_link()
        message_data = {'link': link, 'subject': 'Reset Your Password'}
        self.send_message(message_template='reset_your_password', 
            message_data=message_data)

    def generate_token(self):
        """generate token used for password resets"""
        ts = URLSafeTimedSerializer(FLASK_SECRET_KEY)
        token = ts.dumps(self.email, salt=PASSWORD_RECOVER_KEY)
        return token

    @staticmethod
    def get_user_from_reset_token(token):
        """Returns user if token is right and token not expired"""
        ts = URLSafeTimedSerializer(FLASK_SECRET_KEY)
        email = ts.loads(token, salt=PASSWORD_RECOVER_KEY, max_age=86400)
        if email:
            user = User.objects(email=email).first()
            return user

    def full_name(self):
        return "{} {}".format(self.first_name.encode('utf-8').decode('utf-8'), 
            self.last_name.encode('utf-8').decode('utf-8'))

    def request_two_factor_token(self):
        if not self.authy_id:
            raise Exception('No Authy id for this user')
        sms = authy_api.users.request_sms(self.authy_id, {'force': True})

    def validate_two_factor_token(self, token):
        try:
            verification = authy_api.tokens.verify(
                self.authy_id,
                token
            )
            if not verification.ok():
                self.logger.error('Invalid Token')
                return False
        except AuthyFormatException as e:
            self.logger.error(str(e))
            return False
        return True

    def create_authy(self):
        authy_user = authy_api.users.create(
             self.email,
             self.phone_number,
             1,
        )
        self.authy_id = str(authy_user.id)
        self.save()

    @staticmethod 
    def create(email, password, **kwargs):
        first_name = kwargs.get('first_name', '').strip()
        last_name = kwargs.get('last_name', '').strip()
        middle_name = kwargs.get('middle_name', '').strip()
        trading_account_username = kwargs.get('trading_account_username')
        requires_two_factor = kwargs.get('requires_two_factor', False)
        email = email.lower().strip()
        dob = kwargs.get('dob')
        phone_number = kwargs.get('phone_number')
        dob = Dob(**dob) if dob else dob 
        password = User.hash_password(password)
        user = User.objects(email=email).first()
        if not user:
            user = User(
                email=email, 
                password=password, 
                first_name=first_name, 
                middle_name=middle_name, 
                last_name=last_name, 
                dob=dob,
                phone_number=phone_number,
                trading_account_username=trading_account_username,
                requires_two_factor=requires_two_factor,
            )
            user.save()
            if user.requires_two_factor:
                user.create_authy()
            return user
        else:
            raise Exception('User exists already')

    def send_message(
            self, 
            message_template, 
            message_data={},
            medium='email',  
            attachments=None, 
            alert=None,
        ):
        sender_data = {
            'first_name': self.first_name, 
            'last_name': self.last_name
        }
        if medium == 'sms':
            recipients = [self.phone_number]
        else:
            recipients = [self.email]
        m = Message(
            message_template=message_template,
            user=self,
            sender_data=sender_data, 
            message_data=message_data,
            recipients=recipients,
            medium=medium, 
            attachments=attachments,
            alert=alert,
        )
        m.send()
Exemple #30
0
class Task(Document):
    Target = ReferenceField('Target', reverse_delete_rule=CASCADE)
    Start = DateTimeField()
    End = DateTimeField()
    IsValid = BooleanField(default=True)