Example #1
0
def update_last_action(db_user: User) -> bool:
    """
    Updates the last action field of the user-row in database. Returns boolean if the users session
    is older than one hour or True, when she wants to keep the login

    :param db_user: User in refactored fns, else nickname
    :return: Boolean
    """
    if not db_user or db_user.nickname == nick_of_anonymous_user:
        return False

    timeout_in_sec = 60 * 60 * 24 * 7

    # check difference of
    diff_action = get_now() - db_user.last_action
    diff_login = get_now() - db_user.last_login
    diff_action = diff_action.seconds + diff_action.days * 24 * 60 * 60
    diff_login = diff_login.seconds + diff_login.days * 24 * 60 * 60

    diff = diff_action if diff_action < diff_login else diff_login
    should_log_out = diff > timeout_in_sec and not db_user.settings.keep_logged_in
    db_user.update_last_action()

    transaction.commit()
    return should_log_out
Example #2
0
def __check_in_local_known_user(db_user: User, password: str, _tn) -> dict:
    """
    Tries to check in a local known user.

    :param db_user: current instance of User
    :param password: password of the user
    :param _tn: instance of current translator
    :return: dict()
    """
    LOG.debug("user: %s", db_user.nickname)

    if db_user.validate_password(PW_FOR_LDAP_USER):
        # is ldap
        data = verify_ldap_user_data(db_user.nickname, password, _tn)
        if data['error']:
            LOG.debug("Invalid password for the ldap user")
            return {'error': data['error']}
        else:
            return {'user': db_user}

    # check no-ldap user
    elif db_user.validate_password(password):
        return {'user': db_user}
    else:
        LOG.debug("Invalid password for the local user")
        return {'error': _tn.get(_.userPasswordNotMatch)}
Example #3
0
def get_reputation_of(db_user: User, only_today=False):
    """
    Return the total sum of reputation_borders points for the given nickname

    :param db_user: Should be of type "User"
    :param only_today: Boolean
    :return: Integer and Boolean, if the user is author
    """
    if not db_user:
        return 0, False

    db_reputation = DBDiscussionSession.query(ReputationHistory)

    if only_today:
        today = arrow.utcnow().to('Europe/Berlin')
        db_reputation = db_reputation.filter(
            ReputationHistory.timestamp >= today)

    db_reputation = db_reputation.filter_by(reputator_uid=db_user.uid) \
        .join(ReputationReason, ReputationReason.uid == ReputationHistory.reputation_uid) \
        .all()

    count = sum([rep.reputations.points for rep in db_reputation])

    return count, db_user.is_author() or db_user.is_admin()
Example #4
0
def get_reputation_of(db_user: User, only_today=False):
    """
    Return the total sum of reputation_borders points for the given nickname

    :param db_user: Should be of type "User", but also accepts nickname for legacy support
    :param only_today: Boolean
    :return: Integer and Boolean, if the user is author
    """
    if not isinstance(db_user, User):
        db_user = DBDiscussionSession.query(User).filter_by(nickname=db_user).first()
    count = 0

    if not db_user or db_user.nickname == nick_of_anonymous_user:
        return count, False

    db_reputation = DBDiscussionSession.query(ReputationHistory)

    if only_today:
        today = arrow.utcnow().to('Europe/Berlin')
        db_reputation = db_reputation.filter(ReputationHistory.timestamp >= today)

    db_reputation = db_reputation.filter_by(reputator_uid=db_user.uid) \
        .join(ReputationReason, ReputationReason.uid == ReputationHistory.reputation_uid) \
        .all()

    count = sum([r.reputations.points for r in db_reputation])

    return count, db_user.is_author() or db_user.is_admin()
Example #5
0
def token_to_database(db_user: User, token: Union[str, None]) -> None:
    """
    Store the newly created token in database.

    :param db_user: User
    :param token: new token to be stored
    :return:
    """
    db_user.set_token(token)
    db_user.update_token_timestamp()
    transaction.commit()
Example #6
0
def demote_user(argv=sys.argv):
    if len(argv) < 2:
        print("Please enter a nickname!")
        sys.exit(1)

    username: str = argv[1]

    with transaction.manager:
        try:
            User.by_nickname(username).demote_to_user()
        except NoResultFound:
            print(
                f"The user `{username}` does not exist! Make sure you use the private and not the public nickname!"
            )
            sys.exit(1)
Example #7
0
def get_issues_overview_for(db_user: User,
                            app_url: str) -> Dict[str, Collection]:
    """
    Returns dictionary with keywords 'user' and 'others', which got lists with dicts with infos
    IMPORTANT: URL's are generated for the frontend!

    :param db_user: User
    :param app_url: current applications url
    :return: dict
    """

    if not db_user or db_user.nickname == nick_of_anonymous_user:
        return {'user': [], 'other': []}

    if db_user.is_admin():
        db_issues_other_users = DBDiscussionSession.query(Issue).filter(
            Issue.author_uid != db_user.uid).all()
    else:
        db_issues_other_users = [
            issue for issue in db_user.accessible_issues
            if issue.author_uid != db_user.uid
        ]

    db_issues_of_user = DBDiscussionSession.query(Issue).filter_by(
        author_uid=db_user.uid).order_by(Issue.uid.asc()).all()

    return {
        'user':
        [__create_issue_dict(issue, app_url) for issue in db_issues_of_user],
        'other': [
            __create_issue_dict(issue, app_url)
            for issue in db_issues_other_users
        ]
    }
Example #8
0
def refresh_public_nickname(user: User) -> str:
    """
    Creates and sets a random public nick for the given user

    :param user: The user whose nickname shall be refreshed.
    :return: The new nickname as string
    """
    nick = _random_nickname()
    while DBDiscussionSession.query(User).filter_by(
            public_nickname=nick).first():
        nick = _random_nickname()

    LOG.debug("User %s -> %s", user.public_nickname, nick)
    user.set_public_nickname(nick)

    return nick
Example #9
0
def checks_if_user_is_ldap_user(db_user: User) -> bool:
    """
    Checks if user is ldap user

    :param db_user
    :return:
    """

    pw_for_ldap_user = '******'
    return db_user.validate_password(pw_for_ldap_user)
Example #10
0
def __create_new_user(user,
                      ui_locales,
                      oauth_provider='',
                      oauth_provider_id=''):
    """
    Insert a new user row

    :param user: dict with every information for a user needed
    :param ui_locales: Language.ui_locales
    :param oauth_provider: String
    :param oauth_provider_id: String
    :return: String, String, User
    """
    success = ''
    info = ''

    _t = Translator(ui_locales)
    # creating a new user with hashed password
    LOG.debug("Adding user %s", user['nickname'])
    hashed_password = password_handler.get_hashed_password(user['password'])
    newuser = User(firstname=user['firstname'],
                   surname=user['lastname'],
                   email=user['email'],
                   nickname=user['nickname'],
                   password=hashed_password,
                   gender=user['gender'],
                   group_uid=user['db_group_uid'],
                   oauth_provider=oauth_provider,
                   oauth_provider_id=oauth_provider_id)
    DBDiscussionSession.add(newuser)
    transaction.commit()
    db_user = DBDiscussionSession.query(User).filter_by(
        nickname=user['nickname']).first()
    settings = Settings(author_uid=db_user.uid,
                        send_mails=False,
                        send_notifications=True,
                        should_show_public_nickname=True)
    DBDiscussionSession.add(settings)
    transaction.commit()

    # sanity check, whether the user exists
    db_user = DBDiscussionSession.query(User).filter_by(
        nickname=user['nickname']).first()
    if db_user:
        LOG.debug("New data was added with uid %s", db_user.uid)
        success = _t.get(_.accountWasAdded).format(user['nickname'])

    else:
        LOG.debug("New data was not added")
        info = _t.get(_.accoutErrorTryLateOrContant)

    return success, info, db_user
Example #11
0
def set_settings(url, db_user: User, service, settings_value, _tn):
    """
    Edits a user specific setting

    :param url: current url of request
    :param db_user: User
    :param service: service, which should be modified
    :param settings_value: Boolean
    :param _tn: Translator
    :return: public_nick, public_page_url, gravatar_url, error
    """
    error = ''
    public_nick = db_user.global_nickname
    db_setting = db_user.settings

    if service == 'mail':
        db_setting.set_send_mails(settings_value)
    elif service == 'notification':
        db_setting.set_send_notifications(settings_value)
    elif service == 'public_nick':
        db_setting.set_show_public_nickname(settings_value)
        if settings_value:
            db_user.set_public_nickname(db_user.nickname)
        elif db_user.nickname == db_user.public_nickname:
            user.refresh_public_nickname(db_user)
        public_nick = db_user.global_nickname
    else:
        error = _tn.get(_.keyword)

    transaction.commit()
    public_page_url = '{}/user/{}'.format(url, db_user.uid)
    gravatar_url = get_profile_picture(db_user, 80)

    return {
        'error': error,
        'public_nick': public_nick,
        'public_page_url': public_page_url,
        'gravatar_url': gravatar_url
    }
Example #12
0
def __check_in_local_known_user(db_user: User, password: str, _tn) -> dict:
    """
    Tries to check in a local known user.

    :param db_user: current instance of User
    :param password: password of the user
    :param _tn: instance of current translator
    :return: dict()
    """
    logger('Auth.Login', 'user: {}'.format(db_user.nickname))
    if db_user.validate_password(password):
        return {'user': db_user}

    if not (db_user.validate_password('NO_PW_BECAUSE_LDAP')
            or db_user.password is get_hashed_password('NO_PW_BECAUSE_LDAP')):
        logger('Auth.Login', 'invalid password for the local user')
        return {'error': _tn.get(_.userPasswordNotMatch)}

    data = verify_ldap_user_data(db_user.nickname, password, _tn)
    if data['error']:
        return {'error': data['error']}

    return {'user': db_user}
Example #13
0
def get_last_issue_of(db_user: User) -> Optional[Issue]:
    """
    Returns the last used issue of the user or None

    :param db_user: User
    :return: Issue.uid or 0
    """
    if not db_user or db_user.is_anonymous():
        return None

    db_issue = db_user.settings.last_topic
    if not db_issue:
        return None

    return None if db_issue.is_disabled else db_issue
Example #14
0
    def test_user_to_issues(self):
        db_user: User = User.by_nickname("Björn")
        issue: Issue = DBDiscussionSession.query(Issue).get(8)

        self.assertNotIn(issue, db_user.participates_in)
        db_user.participates_in.append(issue)
        self.assertIn(issue, db_user.participates_in)

        association: UserParticipation = DBDiscussionSession.query(
            UserParticipation).filter_by(user_uid=db_user.uid,
                                         issue_uid=issue.uid).one_or_none()

        self.assertIsNotNone(association)

        DBDiscussionSession.query(UserParticipation).filter_by(
            user_uid=db_user.uid, issue_uid=issue.uid).delete()
Example #15
0
def __create_new_user(user_info: Dict[str, Any],
                      ui_locales: str,
                      oauth_provider: str = '',
                      oauth_provider_id: str = '') -> Tuple[str, str, User]:
    """
    Create a new user.

    :param user_info: A dictionary containing information about the desired user.
    :param ui_locales: Language which shall be used for messaging.
    :param oauth_provider: If applicable: Which oauth-provider is referring the user.
    :param oauth_provider_id: If applicable: The ID of the oauth-provider.
    :return: Returns a tuple containing a success message, a information message and the freshly created user.
    """
    success = ''
    info = ''

    _t = Translator(ui_locales)
    # creating a new user_info with hashed password
    LOG.debug("Adding user_info for %s", user_info['nickname'])
    hashed_password = password_handler.get_hashed_password(
        user_info['password'])
    new_user = User(firstname=user_info['firstname'],
                    surname=user_info['lastname'],
                    email=user_info['email'],
                    nickname=user_info['nickname'],
                    password=hashed_password,
                    gender=user_info['gender'],
                    group_uid=user_info['db_group_uid'],
                    oauth_provider=oauth_provider,
                    oauth_provider_id=oauth_provider_id)
    DBDiscussionSession.add(new_user)
    DBDiscussionSession.flush()
    settings = Settings(author_uid=new_user.uid,
                        send_mails=False,
                        send_notifications=True,
                        should_show_public_nickname=True)
    DBDiscussionSession.add(settings)

    if new_user:
        LOG.debug("New data was added with uid %s", new_user.uid)
        success = _t.get(Keywords.accountWasAdded).format(
            user_info['nickname'])
    else:
        LOG.debug("New data was not added")
        info = _t.get(Keywords.accoutErrorTryLateOrContant)

    return success, info, new_user
Example #16
0
def set_discussions_properties(db_user: User, db_issue: Issue, value,
                               iproperty, translator) -> dict:
    """

    :param db_user: User
    :param db_issue: Issue
    :param value: The value which should be assigned to property
    :param iproperty: Property of Issue, e.g. is_disabled
    :param translator:
    :return:
    """
    if db_issue.author_uid != db_user.uid and not db_user.is_admin():
        return {'error': translator.get(_.noRights)}

    if iproperty == 'enable':
        db_issue.set_disabled(not value)
    elif iproperty == 'public':
        db_issue.set_private(not value)
    elif iproperty == 'writable':
        db_issue.set_read_only(not value)
    else:
        return {'error': translator.get(_.internalKeyError)}

    return {'error': ''}
Example #17
0
def create_speechbubble_dict(bubble_type: BubbleTypes,
                             is_markable: bool = False,
                             is_author: bool = False,
                             uid: str = '',
                             bubble_url: str = '',
                             content: str = '',
                             omit_bubble_url: bool = False,
                             omit_vote_info: bool = False,
                             argument_uid: int = None,
                             statement_uid: int = None,
                             is_supportive: bool = False,
                             db_user: User = None,
                             lang: str = 'en',
                             is_users_opinion: bool = False,
                             other_author: User = None):
    """
    Creates an dictionary which includes every information needed for a bubble.

    :param bubble_type: BubbleTypes
    :param is_markable: True if the content itself could be flagged
    :param is_author: True if the current user is author of the content
    :param uid: Identifier for the bubble
    :param bubble_url: URL for the click event of the bubble
    :param content: Text of the bubble
    :param omit_bubble_url: True if the bubble should have a link
    :param omit_vote_info: True if the bubble have the little, grey information text
    :param argument_uid: Argument.uid
    :param statement_uid: Statement.uid
    :param is_supportive: Boolean
    :param db_user: current
    :param omit_bubble_url: Boolean
    :param lang: is_users_opinion
    :param is_users_opinion: Boolean
    :param other_author:
    :return: dict()
    """
    gravatar_link = get_global_url() + '/static/images/icon.png'
    profile = None

    is_enemy_user = {'admin': False, 'author': False, 'special': False}

    if uid != 'now':
        content = pretty_print_options(content)

    if bubble_type is BubbleTypes.SYSTEM and other_author is not None:
        gravatar_link = get_profile_picture(other_author, 25)
        profile = '/user/{}'.format(other_author.uid),
        is_enemy_user['admin'] = other_author.is_admin()
        is_enemy_user['author'] = other_author.is_author()
        is_enemy_user['special'] = other_author.is_special()

    # check for users opinion
    if bubble_type is BubbleTypes.USER and db_user and db_user.nickname != nick_of_anonymous_user:
        db_marked = None
        gravatar_link = get_profile_picture(db_user, 25)
        if argument_uid is not None and db_user is not None:
            db_marked = DBDiscussionSession.query(MarkedArgument).filter(
                MarkedArgument.argument_uid == argument_uid,
                MarkedArgument.author_uid == db_user.uid).first()

        if statement_uid is not None and db_user is not None:
            db_marked = DBDiscussionSession.query(MarkedStatement).filter(
                MarkedStatement.statement_uid == statement_uid,
                MarkedStatement.author_uid == db_user.uid).first()

        is_users_opinion = db_marked is not None

    speech = {
        'is_user':
        bubble_type is BubbleTypes.USER,
        'is_system':
        bubble_type is BubbleTypes.SYSTEM,
        'is_status':
        bubble_type is BubbleTypes.STATUS,
        'is_info':
        bubble_type is BubbleTypes.INFO,
        'is_markable':
        is_markable,
        'is_author':
        is_author,
        'is_enemy_user':
        is_enemy_user,
        'id':
        uid if len(str(uid)) > 0 else uuid4().hex,
        'bubble_url':
        bubble_url,
        'message':
        content,
        'omit_bubble_url':
        omit_bubble_url,
        'omit_vote_info':
        omit_vote_info,
        'data_type':
        'argument'
        if argument_uid else 'statement' if statement_uid else 'None',
        'data_argument_uid':
        argument_uid,
        'data_statement_uid':
        statement_uid,
        'data_is_supportive':
        is_supportive,
        'is_users_opinion':
        is_users_opinion,
        'enemy': {
            'avatar': gravatar_link,
            'profile': profile,
            'available': profile is not None
        }
    }

    votecount_keys = __get_text_for_click_and_mark_count(
        db_user, bubble_type is BubbleTypes.USER, argument_uid, statement_uid,
        speech, lang)

    speech['votecounts_message'] = votecount_keys[speech['votecounts']]

    return speech
Example #18
0
    def prepare_extras_dict(self,
                            current_slug: str,
                            is_reportable: bool,
                            show_bar_icon: bool,
                            show_graph_icon: bool,
                            registry: Registry,
                            application_url: str,
                            path: str,
                            db_user: User,
                            broke_limit=False,
                            add_premise_container_style='display: none',
                            add_statement_container_style='display: none',
                            ongoing_discussion=True):
        """
        Creates the extras.dict() with many options!

        :param current_slug:
        :param is_reportable: Same as discussion.bubbles.last.is_markable, but TAL has no last indicator
        :param show_bar_icon: True, if the discussion space should show the graph icon
        :param show_graph_icon: True, if the discussion space should show the barometer icon
        :param registry: Pyramids registry
        :param application_url: current app url
        :param path: current path
        :param db_user: User
        :param broke_limit: Boolean
        :param add_premise_container_style: style string, default 'display:none;'
        :param add_statement_container_style: style string, default 'display:none;'
        :param ongoing_discussion: Boolean
        :return: dict()
        """
        LOG.debug("Entering prepare_extras_dict")

        is_user_from_ldap = False
        is_logged_in = False
        nickname = None
        public_nickname = None
        is_user_male = False
        is_user_female = False
        is_admin = False
        is_special = False

        if db_user:
            is_user_from_ldap = db_user.validate_password(PW_FOR_LDAP_USER)
            is_logged_in = True
            nickname = db_user.nickname
            public_nickname = db_user.public_nickname
            is_user_male = db_user.gender == 'm'
            is_user_female = db_user.gender == 'f'
            is_admin = db_user.is_admin()
            is_special = db_user.is_special()
            if db_user.nickname == nick_of_anonymous_user:
                db_user = None
                is_logged_in = False

        return_dict = dict()
        return_dict['url'] = get_global_url()
        return_dict['year'] = datetime.datetime.now().year
        return_dict['restart_url'] = current_slug
        return_dict['is_in_discussion'] = 'discuss' in path
        return_dict['logged_in'] = is_logged_in
        return_dict['nickname'] = nickname
        return_dict['public_nickname'] = public_nickname
        return_dict[
            'add_premise_container_style'] = add_premise_container_style
        return_dict[
            'add_statement_container_style'] = add_statement_container_style
        return_dict['users_avatar'] = get_profile_picture(db_user, 25)
        return_dict['ongoing_discussion'] = ongoing_discussion
        return_dict['slug'] = current_slug
        return_dict['is_user_male'] = is_user_male
        return_dict['is_user_female'] = is_user_female
        return_dict['is_user_neutral'] = not return_dict[
            'is_user_male'] and not return_dict['is_user_female']
        return_dict['broke_limit'] = 'true' if broke_limit else 'false'
        return_dict['use_with_ldap'] = is_user_from_ldap
        return_dict['development_mode'] = is_development_mode(registry)
        return_dict['is_development'] = registry.settings.get(
            'mode', '') == 'development'
        return_dict['is_production'] = registry.settings.get(
            'mode', '') == 'production'
        return_dict['review_count'] = get_complete_review_count(db_user)
        return_dict['modern_bubbles'] = usage_of_modern_bubbles(registry)
        return_dict['usage_of_matomo'] = usage_of_matomo(registry)

        self.add_language_options_for_extra_dict(return_dict)
        is_author, points = get_reputation_of(db_user)
        is_author_bool = is_author or points > limit_to_open_issues

        return_dict['is_reportable'] = is_reportable
        return_dict['is_admin'] = is_admin
        return_dict['is_special'] = is_special
        return_dict['is_author'] = is_author_bool
        return_dict['is_user'] = not (is_admin or is_author_bool or is_special)
        return_dict['show_bar_icon'] = show_bar_icon
        return_dict['show_graph_icon'] = show_graph_icon
        return_dict['close_premise_container'] = True
        return_dict['close_statement_container'] = True
        return_dict['date'] = arrow.utcnow().format('DD-MM-YYYY')
        return_dict['count_of'] = {
            'arguments': DBDiscussionSession.query(Argument).count(),
            'users': DBDiscussionSession.query(User).count(),
            'discussions': DBDiscussionSession.query(Issue).count(),
            'reviews': get_count_of_all(),
        }
        self.__add_title_text(return_dict, is_logged_in)
        self.__add_button_text(return_dict)
        self.__add_tag_text(return_dict)
        self.__add_login_button_properties(return_dict)

        message_dict = dict()
        message_dict['new_count'] = count_of_new_notifications(
            db_user) if db_user else 0
        message_dict['has_unread'] = message_dict['new_count'] > 0
        inbox = get_box_for(db_user, self.system_lang, application_url,
                            True) if db_user else []
        outbox = get_box_for(db_user, self.system_lang, application_url,
                             False) if db_user else []
        message_dict['inbox'] = inbox
        message_dict['outbox'] = outbox
        message_dict['total_in'] = len(inbox)
        message_dict['total_out'] = len(outbox)
        return_dict['notifications'] = message_dict

        return return_dict