Esempio n. 1
0
def user_schema_check_breaches(request: Request) -> UserSchema:
    """Return a UserSchema that will check the password against breaches.

    It would probably be good to generalize this function at some point, probably
    similar to:
    http://webargs.readthedocs.io/en/latest/advanced.html#reducing-boilerplate
    """
    # pylint: disable=unused-argument
    return UserSchema(only=("username", "password"),
                      context={"check_breached_passwords": True})
Esempio n. 2
0
from webargs.pyramidparser import use_kwargs

from tildes.enums import CommentLabelOption, CommentTreeSortOption
from tildes.lib.datetime import utc_now
from tildes.lib.string import separate_string
from tildes.models.comment import Comment, CommentLabel, CommentTree
from tildes.models.group import Group
from tildes.models.topic import Topic
from tildes.models.user import User
from tildes.schemas.user import (
    BIO_MAX_LENGTH,
    EMAIL_ADDRESS_NOTE_MAX_LENGTH,
    UserSchema,
)

PASSWORD_FIELD = UserSchema(only=("password", )).fields["password"]

THEME_OPTIONS = {
    "white": "White",
    "solarized-light": "Solarized Light",
    "solarized-dark": "Solarized Dark",
    "dracula": "Dracula",
    "atom-one-dark": "Atom One Dark",
    "black": "Black",
    "zenburn": "Zenburn",
    "gruvbox-light": "Gruvbox Light",
    "gruvbox-dark": "Gruvbox Dark",
    "motte": "The Motte",
}

Esempio n. 3
0
    request.user = user
    request.db_session.add(Log(LogEventType.USER_LOG_IN, request))

    # only use redirect_url if it's a relative url, so we can't redirect to other sites
    if redirect_url.startswith("/"):
        return HTTPFound(location=redirect_url)

    return HTTPFound(location="/")


@view_config(
    route_name="login", request_method="POST", permission=NO_PERMISSION_REQUIRED
)
@use_kwargs(
    UserSchema(
        only=("username", "password"), context={"username_trim_whitespace": True}
    )
)
@use_kwargs({"from_url": String(missing="")})
@not_logged_in
@rate_limit_view("login")
def post_login(
    request: Request, username: str, password: str, from_url: str
) -> Response:
    """Process a log in request."""
    incr_counter("logins")

    # Look up the user for the supplied username
    user = (
        request.query(User)
        .undefer_all_columns()
Esempio n. 4
0
# Copyright (c) 2018 Tildes contributors <*****@*****.**>
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Root factories for users."""

from pyramid.request import Request

from tildes.models.user import User
from tildes.resources import get_resource
from tildes.schemas.user import UserSchema
from tildes.views.decorators import use_kwargs


@use_kwargs(UserSchema(only=("username", )), location="matchdict")
def user_by_username(request: Request, username: str) -> User:
    """Get a user specified by {username} in the route or 404 if not found."""
    query = request.query(User).include_deleted().filter(
        User.username == username)

    return get_resource(request, query)
Esempio n. 5
0
from pyramid.response import Response
from sqlalchemy.exc import IntegrityError
from webargs.pyramidparser import use_kwargs

from tildes.enums import LogEventType, TopicSortOption
from tildes.lib.string import separate_string
from tildes.models.log import Log
from tildes.models.user import User, UserInviteCode
from tildes.schemas.fields import Enum, ShortTimePeriod
from tildes.schemas.topic import TopicSchema
from tildes.schemas.user import UserSchema
from tildes.views import IC_NOOP
from tildes.views.decorators import ic_view_config


PASSWORD_FIELD = UserSchema(only=("password",)).fields["password"]


@ic_view_config(
    route_name="user",
    request_method="PATCH",
    request_param="ic-trigger-name=password-change",
    permission="change_password",
)
@use_kwargs(
    {
        "old_password": PASSWORD_FIELD,
        "new_password": PASSWORD_FIELD,
        "new_password_confirm": PASSWORD_FIELD,
    }
)
Esempio n. 6
0
"""Views related to user settings."""

from pyramid.httpexceptions import HTTPUnprocessableEntity
from pyramid.request import Request
from pyramid.response import Response
from pyramid.view import view_config
from webargs.pyramidparser import use_kwargs

from tildes.schemas.user import EMAIL_ADDRESS_NOTE_MAX_LENGTH, UserSchema


PASSWORD_FIELD = UserSchema(only=('password',)).fields['password']


@view_config(route_name='settings', renderer='settings.jinja2')
def get_settings(request: Request) -> dict:
    """Generate the user settings page."""
    current_theme = request.cookies.get('theme', '')
    theme_options = {
        '': 'White (default)',
        'light': 'Solarized Light',
        'dark': 'Solarized Dark',
        'black': 'Black',
    }

    return {'current_theme': current_theme, 'theme_options': theme_options}


@view_config(
    route_name='settings_account_recovery',
    renderer='settings_account_recovery.jinja2',
Esempio n. 7
0
    permission=NO_PERMISSION_REQUIRED,
)
@not_logged_in
def get_login(request: Request) -> dict:
    """Display the login form."""
    # pylint: disable=unused-argument
    return {}


@view_config(
    route_name='login',
    request_method='POST',
    permission=NO_PERMISSION_REQUIRED,
)
@use_kwargs(
    UserSchema(only=('username', 'password'), strict=True), )
@not_logged_in
@rate_limit_view('login')
def post_login(request: Request, username: str, password: str) -> HTTPFound:
    """Process a log in request."""
    incr_counter('logins')

    # Look up the user for the supplied username
    user = (request.query(User).undefer_all_columns().filter(
        User.username == username).one_or_none())

    # If that user doesn't exist or the password was wrong, error out
    if not user or not user.is_correct_password(password):
        incr_counter('login_failures')

        # log the failure - need to manually commit because of the exception
Esempio n. 8
0
"""Root factories for users."""

from pyramid.request import Request
from webargs.pyramidparser import use_kwargs

from tildes.models.user import User
from tildes.resources import get_resource
from tildes.schemas.user import UserSchema


@use_kwargs(
    UserSchema(only=('username', )),
    locations=('matchdict', ),
)
def user_by_username(request: Request, username: str) -> User:
    """Get a user specified by {username} in the route or 404 if not found."""
    query = request.query(User).filter(User.username == username)

    return get_resource(request, query)
Esempio n. 9
0
    route_name="register", renderer="register.jinja2", permission=NO_PERMISSION_REQUIRED
)
@use_kwargs({"code": String(missing="")})
@not_logged_in
def get_register(request: Request, code: str) -> dict:
    """Display the registration form."""
    # pylint: disable=unused-argument
    return {"code": code}


@view_config(
    route_name="register", request_method="POST", permission=NO_PERMISSION_REQUIRED
)
@use_kwargs(
    UserSchema(
        only=("username", "password"), context={"check_breached_passwords": True}
    ),
    location="form",
)
@use_kwargs(
    {"invite_code": String(required=True), "password_confirm": String(required=True)},
    location="form",
)
@not_logged_in
@rate_limit_view("register")
def post_register(
    request: Request,
    username: str,
    password: str,
    password_confirm: str,
    invite_code: str,
Esempio n. 10
0
from pyramid.request import Request
from pyramid.response import Response
from sqlalchemy.exc import IntegrityError
from webargs.pyramidparser import use_kwargs

from tildes.enums import LogEventType, TopicSortOption
from tildes.models.log import Log
from tildes.models.user import User, UserInviteCode
from tildes.schemas.fields import Enum, ShortTimePeriod
from tildes.schemas.topic import TopicSchema
from tildes.schemas.user import UserSchema
from tildes.views import IC_NOOP
from tildes.views.decorators import ic_view_config


PASSWORD_FIELD = UserSchema(only=('password',)).fields['password']


@ic_view_config(
    route_name='user',
    request_method='PATCH',
    request_param='ic-trigger-name=password-change',
    permission='change_password',
)
@use_kwargs({
    'old_password': PASSWORD_FIELD,
    'new_password': PASSWORD_FIELD,
    'new_password_confirm': PASSWORD_FIELD,
})
def change_password(
        request: Request,