Пример #1
0
def insert(userid, target_user, parentid, content, staffnotes):
    # Check invalid content
    if not content:
        raise WeasylError("commentInvalid")
    elif not target_user or not d.is_vouched_for(target_user):
        raise WeasylError("Unexpected")

    # Determine parent userid
    if parentid:
        parentuserid = d.engine.scalar(
            "SELECT userid FROM comments WHERE commentid = %(parent)s",
            parent=parentid,
        )

        if parentuserid is None:
            raise WeasylError("shoutRecordMissing")
    else:
        parentuserid = None

    # Check permissions
    if userid not in staff.MODS:
        if ignoreuser.check(target_user, userid):
            raise WeasylError("pageOwnerIgnoredYou")
        elif ignoreuser.check(userid, target_user):
            raise WeasylError("youIgnoredPageOwner")
        elif ignoreuser.check(parentuserid, userid):
            raise WeasylError("replyRecipientIgnoredYou")
        elif ignoreuser.check(userid, parentuserid):
            raise WeasylError("youIgnoredReplyRecipient")

        _, is_banned, _ = d.get_login_settings(target_user)
        profile_config = d.get_config(target_user)

        if is_banned or "w" in profile_config or "x" in profile_config and not frienduser.check(
                userid, target_user):
            raise WeasylError("insufficientActionPermissions")

    # Create comment
    settings = 's' if staffnotes else ''
    co = d.meta.tables['comments']
    db = d.connect()
    commentid = db.scalar(co.insert().values(userid=userid,
                                             target_user=target_user,
                                             parentid=parentid or None,
                                             content=content,
                                             unixtime=arrow.utcnow(),
                                             settings=settings).returning(
                                                 co.c.commentid))

    # Create notification
    if parentid and userid != parentuserid:
        if not staffnotes or parentuserid in staff.MODS:
            welcome.shoutreply_insert(userid, commentid, parentuserid,
                                      parentid, staffnotes)
    elif not staffnotes and target_user and userid != target_user:
        welcome.shout_insert(userid, commentid, otherid=target_user)

    d.metric('increment', 'shouts')

    return commentid
Пример #2
0
def select_profile(userid, viewer=None):
    query = d.engine.execute("""
        SELECT pr.username, pr.full_name, pr.catchphrase, pr.created_at, pr.profile_text,
            pr.settings, pr.stream_url, pr.config, pr.stream_text, us.end_time
        FROM profile pr
            INNER JOIN login lo USING (userid)
            LEFT JOIN user_streams us USING (userid)
        WHERE userid = %(user)s
    """,
                             user=userid).first()

    if not query:
        raise WeasylError('userRecordMissing')

    is_banned, is_suspended = d.get_login_settings(userid)

    streaming_status = "stopped"
    if query[6]:  # profile.stream_url
        if 'l' in query[5]:
            streaming_status = "later"
        elif query[9] is not None and query[9] > d.get_time(
        ):  # user_streams.end_time
            streaming_status = "started"

    return {
        "userid": userid,
        "user_media": media.get_user_media(userid),
        "username": query[0],
        "full_name": query[1],
        "catchphrase": query[2],
        "unixtime": query[3],
        "profile_text": query[4],
        "settings": query[5],
        "stream_url": query[6],
        "stream_text": query[8],
        "config": query[7],
        "show_favorites_bar": "u" not in query[7] and "v" not in query[7],
        "show_favorites_tab": userid == viewer or "v" not in query[7],
        "commish_slots": 0,
        "banned": is_banned,
        "suspended": is_suspended,
        "streaming_status": streaming_status,
    }
Пример #3
0
def authenticate_bcrypt(username, password, request, ip_address=None, user_agent=None):
    """
    Return a result tuple of the form (userid, error); `error` is None if the
    login was successful. Pass None as the `request` to authenticate a user
    without creating a new session.

    :param username: The username of the user attempting authentication.
    :param password: The user's claimed password to check against the stored hash.
    :param request: The request, or None
    :param ip_address: The address requesting authentication.
    :param user_agent: The user agent string of the submitting client.

    Possible errors are:
    - "invalid"
    - "unexpected"
    - "banned"
    - "suspended"
    - "2fa" - Indicates the user has opted-in to 2FA. Additional authentication required.
    """
    # Check that the user entered potentially valid values for `username` and
    # `password` before attempting to authenticate them
    if not username or not password:
        return 0, "invalid"

    # Select the authentication data necessary to check that the the user-entered
    # credentials are valid
    query = d.engine.execute(
        "SELECT ab.userid, ab.hashsum, lo.twofa_secret FROM authbcrypt ab"
        " RIGHT JOIN login lo USING (userid)"
        " WHERE lo.login_name = %(name)s",
        name=d.get_sysname(username),
    ).first()

    if not query:
        return 0, "invalid"

    USERID, HASHSUM, TWOFA = query
    HASHSUM = HASHSUM.encode('utf-8')
    _, IS_BANNED, IS_SUSPENDED = d.get_login_settings(USERID)

    d.metric('increment', 'attemptedlogins')

    if not bcrypt.checkpw(password.encode('utf-8'), HASHSUM):
        # Log the failed login attempt in a security log if the account the user
        # attempted to log into is a privileged account
        if USERID in staff.MODS:
            d.append_to_log('login.fail', userid=USERID, ip=d.get_address())
            d.metric('increment', 'failedlogins')

        # Return a zero userid and an error code (indicating the entered password
        # was incorrect)
        return 0, "invalid"
    elif IS_BANNED:
        # Return the proper userid and an error code (indicating the user's account
        # has been banned)
        return USERID, "banned"
    elif IS_SUSPENDED:
        from weasyl import moderation
        suspension = moderation.get_suspension(USERID)

        if d.get_time() > suspension.release:
            d.execute("DELETE FROM suspension WHERE userid = %i", [USERID])
            d._get_all_config.invalidate(USERID)
        else:
            # Return the proper userid and an error code (indicating the user's
            # account has been temporarily suspended)
            return USERID, "suspended"

    # Attempt to create a new session if this is a request to log in, then log the signin
    # if it succeeded.
    if request is not None:
        # If the user's record has ``login.twofa_secret`` set (not nulled), return that password authentication succeeded.
        if TWOFA:
            if not isinstance(request.weasyl_session, GuestSession):
                request.pg_connection.delete(request.weasyl_session)
                request.pg_connection.flush()
            request.weasyl_session = create_session(None)
            request.weasyl_session.additional_data = {}
            return USERID, "2fa"
        else:
            signin(request, USERID, ip_address=ip_address, user_agent=user_agent)

    # Either way, authentication succeeded, so return the userid and a status.
    return USERID, None