Example #1
0
    def authenticate_user(self, user: IUser, login_source:str, location: str=None):
        """Make the current session logged in session for this particular user."""
        request = self.request
        settings = request.registry.settings

        require_activation = asbool(settings.get('horus.require_activation', True))
        allow_inactive_login = asbool(settings.get('horus.allow_inactive_login', False))

        if (not allow_inactive_login) and require_activation and (not user.is_activated()):
            raise AuthenticationFailure('Your account is not active, please check your e-mail. If your account activation email as expired please request a password reset.')

        if not user.can_login():
            raise AuthenticationFailure('This user account cannot log in at the moment.')

        user_registry = get_user_registry(request)
        token = user_registry.get_session_token(user)
        headers = remember(request, token)
        # assert headers, "Authentication backend did not give us any session headers"

        if not location:
            location = get_config_route(request, 'horus.login_redirect')

        self.greet_user(user)

        self.update_login_data(user)

        e = events.Login(request, user)
        request.registry.notify(e)

        return HTTPFound(location=location, headers=headers)
Example #2
0
    def activate_by_email(self,
                          activation_code: str,
                          location: str = None) -> Response:
        """Active a user after user after the activation email.

            * User clicks link in the activation email
            * User enters the activation code on the form by hand

        :param activation_code: Activation code for user account.
        :param location: URL to redirct the user to, after activation.
        :raise: HTTPNotFound is activation_code is invalid.
        :return: Redirect to location.
        """
        request = self.request
        settings = request.registry.settings
        user_registry = get_user_registry(request)

        after_activate_url = request.route_url(
            settings.get('websauna.activate_redirect', 'index'))
        login_after_activation = asbool(
            settings.get('websauna.login_after_activation', False))

        user = user_registry.activate_user_by_email_token(activation_code)
        if not user:
            raise HTTPNotFound("Activation code not found")

        if login_after_activation:
            login_service = get_login_service(self.request)
            return login_service.authenticate_user(user, login_source="email")
        else:
            self.request.registry.notify(
                RegistrationActivatedEvent(self.request, user, None))
            return HTTPFound(location=location or after_activate_url)
Example #3
0
    def check_credentials(self, username: str, password: str) -> UserMixin:
        """Check if the user password matches.

        * First try username + password
        + Then try with email + password

        :param username: username or email
        :param password:
        :raise websauna.system.user.interfaces.AuthenticationFailure: On login problem.
        :return: User object which was picked
        """
        request = self.request
        settings = request.registry.settings
        allow_email_auth = settings.get('websauna.allow_email_auth', True)

        # Check login with username
        user_registry = get_user_registry(request)
        user = user_registry.get_authenticated_user_by_username(username, password)

        # Check login with email
        if allow_email_auth and not user:
            user = user_registry.get_authenticated_user_by_email(username, password)

        if not user:
            raise AuthenticationFailure('Invalid username or password.')

        return user
Example #4
0
    def check_credentials(self, username: str, password: str) -> UserMixin:
        """Check if the user password matches.

        * First try username + password

        + Then try with email + password

        :param username: username or email
        :param password:
        :raise horus.exceptionsAuthenticationFailure: On login problem. TODO: Exception class to be changed.
        :return: User object which was picked
        """
        request = self.request
        settings = request.registry.settings
        allow_email_auth = settings.get('horus.allow_email_auth', False)

        # Check login with username
        user_registry = get_user_registry(request)
        user = user_registry.get_authenticated_user_by_username(
            username, password)

        # Check login with email
        if allow_email_auth and not user:
            user = user_registry.get_authenticated_user_by_email(
                username, password)

        if not user:
            raise AuthenticationFailure('Invalid username or password.')

        return user
Example #5
0
def create(request, username, email, password=None, source="command_line", admin=False):
    """Create a new site user from command line.

    :param request:
    :param username:
    :param email:
    :param password:
    :param source:
    :param admin: Set this user to admin. The first user is always implicitly admin.
    :return:
    """
    User = get_user_class(request.registry)
    dbsession = request.dbsession
    u = dbsession.query(User).filter_by(email=email).first()
    if u is not None:
        return u

    u = User(email=email, username=username)

    if password:
        user_registry = get_user_registry(request)
        user_registry.set_password(u, password)

    u.registration_source = source
    u.activated_at = now()
    dbsession.add(u)
    dbsession.flush()

    request.registry.notify(UserCreated(request, u))

    if admin:
        group = dbsession.query(Group).filter_by(name="admin").one_or_none()
        group.users.append(u)

    return u
    def activate_by_email(self, activation_code: str, location=None) -> Response:
        """Active a user after user after the activation email.

        * User clicks link in the activation email

        * User enters the activation code on the form by hand
        """

        request = self.request
        settings = request.registry.settings
        user_registry = get_user_registry(request)

        after_activate_url = request.route_url(settings.get('websauna.activate_redirect', 'index'))
        login_after_activation = asbool(settings.get('websauna.login_after_activation', False))

        user = user_registry.activate_user_by_email_token(activation_code)
        if not user:
            raise HTTPNotFound("Activation code not found")

        if login_after_activation:
            login_service = get_login_service(self.request.registry)
            return login_service.authenticate(self.request, user)
        else:
            self.request.registry.notify(RegistrationActivatedEvent(self.request, user, None))
            return HTTPFound(location=location or after_activate_url)
Example #7
0
    def activate_by_email(self,
                          activation_code: str,
                          location=None) -> Response:
        """Active a user after user after the activation email.

        * User clicks link in the activation email

        * User enters the activation code on the form by hand
        """

        request = self.request
        dbsession = self.request.dbsession
        settings = request.registry.settings
        user_registry = get_user_registry(request)

        after_activate_url = request.route_url(
            settings.get('horus.activate_redirect', 'index'))
        login_after_activation = asbool(
            settings.get('horus.login_after_activation', False))

        user = user_registry.activate_user_by_email_token(activation_code)
        if not user:
            raise HTTPNotFound("Activation code not found")

        if login_after_activation:
            login_service = get_login_service(self.request.registry)
            return login_service.authenticate(self.request, user)
        else:
            self.request.registry.notify(
                RegistrationActivatedEvent(self.request, user, None))
            return HTTPFound(location=location or after_activate_url)
Example #8
0
    def sign_up(self, user_data: dict) -> Response:
        """Sign up a new user."""

        user_registry = get_user_registry(self.request)
        user = user_registry.sign_up(registration_source="email", user_data=user_data)

        # Notify site creator to initialize the admin for the first user
        self.request.registry.notify(UserCreated(self.request, user))

        settings = self.request.registry.settings

        require_activation = asbool(settings.get('websauna.require_activation', True))
        autologin = asbool(settings.get('websauna.autologin', False))

        if require_activation:
            self.create_email_activation(user)
        elif not autologin:
            messages.add(self.request, msg_id="msg-sign-up-complete", msg="Sign up complete. Welcome!", kind="success")

        self.request.registry.notify(NewRegistrationEvent(self.request, user, None, user_data))

        self.request.dbsession.flush()  # in order to get the id
        if autologin:
            login_service = get_login_service(self.request.registry)
            return login_service.authenticate(self.request, user)
        else:  # not autologin: user must log in just after registering.
            return render_to_response('login/waiting_for_activation.html', {"user": user}, request=self.request)
Example #9
0
    def check_credentials(self, username: str, password: str) -> UserMixin:
        """Check if the user password matches.

        * First try username + password

        + Then try with email + password

        :param username: username or email
        :param password:
        :raise horus.exceptionsAuthenticationFailure: On login problem. TODO: Exception class to be changed.
        :return: User object which was picked
        """
        request = self.request
        settings = request.registry.settings
        allow_email_auth = settings.get('horus.allow_email_auth', False)

        # Check login with username
        user_registry = get_user_registry(request)
        user = user_registry.get_authenticated_user_by_username(username, password)

        # Check login with email
        if allow_email_auth and not user:
            user = user_registry.get_authenticated_user_by_email(username, password)

        if not user:
            raise AuthenticationFailure('Invalid username or password.')

        return user
Example #10
0
    def check_credentials(self, username: str, password: str) -> UserMixin:
        """Check if the user password matches.

        * First try username + password

        + Then try with email + password

        :param username: username or email
        :param password:
        :raise websauna.system.user.interfaces.AuthenticationFailure: On login problem.
        :return: User object which was picked
        """
        request = self.request
        settings = request.registry.settings
        allow_email_auth = settings.get('websauna.allow_email_auth', True)

        # Check login with username
        user_registry = get_user_registry(request)
        user = user_registry.get_authenticated_user_by_username(username, password)

        # Check login with email
        if allow_email_auth and not user:
            user = user_registry.get_authenticated_user_by_email(username, password)

        if not user:
            raise AuthenticationFailure('Invalid username or password.')

        return user
    def create_forgot_password_request(self, email, location=None) -> Response:
        """Create a new email activation token for a user and produce the following screen.

        * Sets user password reset token

        * Sends out reset password email

        * The existing of user with such email should be validated beforehand

        :raise: CannotResetPasswordException if there is any reason the password cannot be reset. Usually wrong email.
        """

        request = self.request

        user_registry = get_user_registry(request)

        reset_info = user_registry.create_password_reset_token(email)
        if not reset_info:
            raise CannotResetPasswordException("Cannot reset password for email: {}".format(email))
        user, token, expiration_seconds = reset_info

        link = request.route_url('reset_password', code=token)
        context = dict(link=link, user=user, expiration_hours=int(expiration_seconds/3600))
        send_templated_mail(request, [email,], "login/email/forgot_password", context=context)

        messages.add(request, msg="Please check your email to continue password reset.", kind='success', msg_id="msg-check-email")

        if not location:
            location = get_config_route(request, 'websauna.request_password_reset_redirect')
            assert location

        return HTTPFound(location=location)
Example #12
0
    def reset_password(self,
                       activation_code: str,
                       password: str,
                       location=None) -> Response:
        """Perform actual password reset operations.

        User has following password reset link (GET) or enters the code on a form.
        """
        request = self.request
        user_registry = get_user_registry(request)
        user = user_registry.get_user_by_password_reset_token(activation_code)
        if not user:
            return HTTPNotFound("Activation code not found")

        user_registry.reset_password(user, password)

        messages.add(
            request,
            msg=
            "The password reset complete. Please sign in with your new password.",
            kind='success',
            msg_id="msg-password-reset-complete")

        request.registry.notify(
            PasswordResetEvent(self.request, user, password))
        request.registry.notify(
            UserAuthSensitiveOperation(self.request, user, "password_reset"))

        location = location or get_config_route(
            request, 'horus.reset_password_redirect')
        return HTTPFound(location=location)
Example #13
0
    def save_changes(self, form: deform.Form, appstruct: dict, obj: User):

        # Set hashed password
        user_registry = get_user_registry(self.request)
        user_registry.set_password(obj, appstruct["password"])

        # Drop session
        kill_user_sessions(self.request, obj, "password_change")
Example #14
0
    def save_changes(self, form: deform.Form, appstruct: dict, obj: User):

        # Set hashed password
        user_registry = get_user_registry(self.request)
        user_registry.set_password(obj, appstruct["password"])

        # Drop session
        kill_user_sessions(self.request, obj, "password_change")
    def get_user_for_password_reset_token(self, activation_code: str) -> IUser:
        """Get a user by activation token.

        """
        request = self.request
        user_registry = get_user_registry(request)
        user = user_registry.get_user_by_password_reset_token(activation_code)
        return user
Example #16
0
    def get_user_for_password_reset_token(self, activation_code: str) -> IUser:
        """Get a user by activation token.

        """
        request = self.request
        user_registry = get_user_registry(request)
        user = user_registry.get_user_by_password_reset_token(activation_code)
        return user
Example #17
0
    def authenticate_user(self,
                          user: IUser,
                          login_source: str,
                          location: str = None) -> Response:
        """Make the current session logged in session for this particular user.

        How to authenticate user using the login service (assuming you have done password match or related yourself):

        .. code-block:: python

            from websauna.system.user.utils import get_login_service

            def my_view(request):

                # load user model instance from database
                # user = ...

                login_service = get_login_service(request)
                response = login_service.authenticate_user(user, "my-login-source")

        :raise AuthenticationFailure: If login cannot proceed due to disabled user account, etc.

        :return: HTTPResponse what should happen as post-login action
        """
        request = self.request
        settings = request.registry.settings

        require_activation = asbool(
            settings.get('websauna.require_activation', True))
        allow_inactive_login = asbool(
            settings.get('websauna.allow_inactive_login', False))

        if (not allow_inactive_login) and require_activation and (
                not user.is_activated()):
            raise AuthenticationFailure(
                'Your account is not active, please check your e-mail. If your account activation email as expired please request a password reset.'
            )

        if not user.can_login():
            raise AuthenticationFailure(
                'This user account cannot log in at the moment.')

        user_registry = get_user_registry(request)
        token = user_registry.get_session_token(user)
        headers = remember(request, token)
        # assert headers, "Authentication backend did not give us any session headers"

        if not location:
            location = get_config_route(request, 'websauna.login_redirect')

        self.greet_user(user)

        self.update_login_data(user)

        e = events.Login(request, user)
        request.registry.notify(e)

        return HTTPFound(location=location, headers=headers)
Example #18
0
def validate_user_exists_with_email(node, val):
    '''Colander validator that ensures a User exists with the email.'''
    request = node.bindings['request']

    user_registry = get_user_registry(request)
    user = user_registry.get_by_email(val)

    if not user:
        raise c.Invalid(node, "Cannot reset password for such email: {}".format(val))
Example #19
0
def validate_user_exists_with_email(node, val):
    '''Colander validator that ensures a User exists with the email.'''
    request = node.bindings['request']

    user_registry = get_user_registry(request)
    user = user_registry.get_by_email(val)

    if not user:
        raise c.Invalid(node,
                        "Cannot reset password for such email: {}".format(val))
Example #20
0
    def save_changes(self, form: deform.Form, appstruct: dict, obj: User):
        """Save the form data.

        :param form: Form object.
        :param appstruct: Form data.
        :param user: User object.
        """
        # Set hashed password
        user_registry = get_user_registry(self.request)
        user_registry.set_password(obj, appstruct["password"])

        # Drop session
        kill_user_sessions(self.request, obj, "password_change")
Example #21
0
def get_user(session_token: str, request: Request) -> t.Optional[User]:
    """Extract the logged in user from the request object using Pyramid's authentication framework."""
    # user_id = unauthenticated_userid(request)
    # TODO: Abstract this to its own service like in Warehouse?
    user_registry = get_user_registry(request)
    user = None
    if session_token is not None:
        user = user_registry.get_user_by_session_token(session_token)
        # Check through conditions why this user would no longer be valid
        if user and not user.can_login():
            # User account disabled while in mid-session
            user = None
    return user
Example #22
0
def resolve_principals(session_token: str,
                       request: Request) -> Optional[List[str]]:
    """Get applied groups and other for the user.

    This is a callback for :py:class:`pyramid.authentication.SessionAuthenticationPolicy`.

    * List all groups as ``group:admin`` style strings

    * List super user as ``superuser:superuser`` style string

    :return: None if the user is not logged in, otherwise list of principals assigned to the user site wide.
    """

    user_registry = get_user_registry(request)
    user = user_registry.get_user_by_session_token(session_token)
    if not user:
        return None

    settings = request.registry.settings

    # Read superuser names from the config
    superusers = aslist(settings.get("websauna.superusers"))

    admin_as_superuser = asbool(
        settings.get("websauna.admin_as_superuser", False))

    if user_registry.can_login(user):

        # Users always get Authenticated special principal
        principals = [Authenticated]

        # All groups for this user
        principals += [
            'group:{}'.format(g.name) for g in user_registry.get_groups(user)
        ]

        # Give principal for per user permissions
        principals += ['user:{}'.format(user.id)]

        # Allow superuser permission
        if user.username in superusers or user.email in superusers:
            # Superuser explicitly listed in the configuration
            principals.append("superuser:superuser")
        elif admin_as_superuser and ("group:admin" in principals):
            # Automatically promote admins to superusers when doing local development
            principals.append("superuser:superuser")

        return principals

    # User not found, user disabled
    return None
Example #23
0
def validate_user_exists_with_email(node: c.SchemaNode, value: str):
    """Colander validator that ensures a User exists with the email.'

    :param node: Colander SchemaNode.
    :param value: Email address.
    :raises: c.Invalid if email is not registered for an User.
    """
    request = node.bindings['request']

    user_registry = get_user_registry(request)
    user = user_registry.get_by_email(value)

    if not user:
        raise c.Invalid(node, "Cannot reset password for such email: {email}".format(email=value))
Example #24
0
    def authenticate_user(self, user: IUser, login_source: str, location: str=None) -> Response:
        """Make the current session logged in session for this particular user.

        How to authenticate user using the login service (assuming you have done password match or related yourself):

        .. code-block:: python

            from websauna.system.user.utils import get_login_service

            def my_view(request):

                # load user model instance from database
                # user = ...

                login_service = get_login_service(request)
                response = login_service.authenticate_user(user, "my-login-source")

        :raise AuthenticationFailure: If login cannot proceed due to disabled user account, etc.

        :return: HTTPResponse what should happen as post-login action
        """
        request = self.request
        settings = request.registry.settings

        require_activation = asbool(settings.get('websauna.require_activation', True))
        allow_inactive_login = asbool(settings.get('websauna.allow_inactive_login', False))

        if (not allow_inactive_login) and require_activation and (not user.is_activated()):
            raise AuthenticationFailure('Your account is not active, please check your e-mail. If your account activation email as expired please request a password reset.')

        if not user.can_login():
            raise AuthenticationFailure('This user account cannot log in at the moment.')

        user_registry = get_user_registry(request)
        token = user_registry.get_session_token(user)
        headers = remember(request, token)
        # assert headers, "Authentication backend did not give us any session headers"

        if not location:
            location = get_config_route(request, 'websauna.login_redirect')

        self.greet_user(user)

        self.update_login_data(user)

        e = events.Login(request, user)
        request.registry.notify(e)

        return HTTPFound(location=location, headers=headers)
Example #25
0
def resolve_principals(session_token: str, request: Request) -> Optional[List[str]]:
    """Get applied groups and other for the user.

    This is a callback for :py:class:`pyramid.authentication.SessionAuthenticationPolicy`.

    * List all groups as ``group:admin`` style strings

    * List super user as ``superuser:superuser`` style string

    :return: None if the user is not logged in, otherwise list of principals assigned to the user site wide.
    """

    user_registry = get_user_registry(request)
    user = user_registry.get_user_by_session_token(session_token)
    if not user:
        return None

    settings = request.registry.settings

    # Read superuser names from the config
    superusers = aslist(settings.get("websauna.superusers"))

    admin_as_superuser = asbool(settings.get("websauna.admin_as_superuser", False))

    if user_registry.can_login(user):

        # Users always get Authenticated special principal
        principals = [Authenticated]

        # All groups for this user
        principals += ['group:{}'.format(g.name) for g in user_registry.get_groups(user)]

        # Give principal for per user permissions
        principals += ['user:{}'.format(user.id)]

        # Allow superuser permission
        if user.username in superusers or user.email in superusers:
            # Superuser explicitly listed in the configuration
            principals.append("superuser:superuser")
        elif admin_as_superuser and ("group:admin" in principals):
            # Automatically promote admins to superusers when doing local development
            principals.append("superuser:superuser")

        return principals

    # User not found, user disabled
    return None
Example #26
0
    def create_forgot_password_request(self,
                                       email: str,
                                       location: str = None) -> Response:
        """Create a new email activation token for a user and produce the following screen.

        * Sets user password reset token
        * Sends out reset password email
        * The existing of user with such email should be validated beforehand

        :param email: User email.
        :param location: URL to redirect the user after the password request.
        :return: Redirect to location.
        :raise: CannotResetPasswordException if there is any reason the password cannot be reset. Usually wrong email.
        """
        request = self.request

        user_registry = get_user_registry(request)

        reset_info = user_registry.create_password_reset_token(email)
        if not reset_info:
            raise CannotResetPasswordException(
                "Cannot reset password for email: {email}".format(email=email))
        user, token, expiration_seconds = reset_info

        link = request.route_url('reset_password', code=token)
        context = dict(link=link,
                       user=user,
                       expiration_hours=int(expiration_seconds / 3600))
        send_templated_mail(request, [
            email,
        ],
                            "login/email/forgot_password",
                            context=context)

        messages.add(request,
                     msg="Please check your email to continue password reset.",
                     kind='success',
                     msg_id="msg-check-email")

        if not location:
            location = get_config_route(
                request, 'websauna.request_password_reset_redirect')
            assert location

        return HTTPFound(location=location)
Example #27
0
    def create_email_activation(self, user: IUser):
        """Create through-the-web user sign up with his/her email.

        We don't want to force the users to pick up an usernames, so we just generate an username.
        The user is free to change their username later.
        """

        user_registry = get_user_registry(self.request)
        activation_code, expiration_seconds = user_registry.create_email_activation_token(user)

        context = {
            'link': self.request.route_url('activate', code=activation_code),
            'expiration_hours': int(expiration_seconds/3600),
        }

        logger.info("Sending sign up email to %s", user.email)

        # TODO: Broken abstraction, we assume user.email is a attribute
        send_templated_mail(self.request, [user.email], "login/email/activate", context)
Example #28
0
def resolve_principals(session_token: str,
                       request: Request) -> Optional[List[str]]:
    """Get applied groups and other for the user.

    This is a callback for :py:class:`pyramid.authentication.SessionAuthenticationPolicy`.

    * List all groups as ``group:admin`` style strings

    * List super user as ``superuser:superuser`` style string
    """

    # TODO: Abstract this to its own service like in Warehouse?
    user_registry = get_user_registry(request)
    user = user_registry.get_user_by_session_token(session_token)
    if not user:
        return None

    settings = request.registry.settings

    # Read superuser names from the config
    superusers = aslist(settings.get("websauna.superusers"))

    admin_as_superuser = asbool(
        settings.get("websauna.admin_as_superuser", False))

    if user_registry.can_login(user):

        principals = [
            'group:{}'.format(g.name) for g in user_registry.get_groups(user)
        ]

        # Allow superuser permission
        if user.username in superusers or user.email in superusers:
            # Superuser explicitly listed in the configuration
            principals.append("superuser:superuser")
        elif admin_as_superuser and ("group:admin" in principals):
            # Automatically promote admins to superusers when doing local development
            principals.append("superuser:superuser")

        return principals

    # User not found, user disabled
    return None
Example #29
0
def get_user(session_token: str, request: Request) -> User:
    """Extract the logged in user from the request object using Pyramid's authentication framework."""

    # user_id = unauthenticated_userid(request)

    # TODO: Abstract this to its own service like in Warehouse?
    user_registry = get_user_registry(request)

    if session_token is not None:
        user = user_registry.get_user_by_session_token(session_token)

        # Check through conditions why this user would no longer be valid
        if user:
            if not user.can_login():
               # User account disabled while in mid-session
               return None

        return user

    return None
    def reset_password(self, activation_code: str, password: str, location=None) -> Response:
        """Perform actual password reset operations.

        User has following password reset link (GET) or enters the code on a form.
        """
        request = self.request
        user_registry = get_user_registry(request)
        user = user_registry.get_user_by_password_reset_token(activation_code)
        if not user:
            return HTTPNotFound("Activation code not found")

        user_registry.reset_password(user, password)

        messages.add(request, msg="The password reset complete. Please sign in with your new password.", kind='success', msg_id="msg-password-reset-complete")

        request.registry.notify(PasswordResetEvent(self.request, user, password))
        request.registry.notify(UserAuthSensitiveOperation(self.request, user, "password_reset"))

        location = location or get_config_route(request, 'websauna.reset_password_redirect')
        return HTTPFound(location=location)
Example #31
0
def create(
        request,
        username: str,
        email: str,
        password: t.Optional[str]=None,
        source: str='command_line',
        admin: bool=False
) -> IUserModel:
    """Create a new site user from command line.

    :param request:
    :param username: Username, usually an email.
    :param email: User's email.
    :param password: Password.
    :param source: Source of this user, in here, command_line.
    :param admin: Set this user to admin. The first user is always implicitly admin.
    :return: Newly created user.
    """
    User = get_user_class(request.registry)
    dbsession = request.dbsession
    u = dbsession.query(User).filter_by(email=email).first()
    if u is not None:
        return u

    u = User(email=email, username=username)
    dbsession.add(u)
    dbsession.flush()  # Make sure u.user_data is set

    if password:
        user_registry = get_user_registry(request)
        user_registry.set_password(u, password)

    u.registration_source = source
    u.activated_at = now()

    request.registry.notify(UserCreated(request, u))
    if admin:
        group = dbsession.query(Group).filter_by(name='admin').one_or_none()
        group.users.append(u)

    return u
Example #32
0
def create(request,
           username,
           email,
           password=None,
           source="command_line",
           admin=False):
    """Create a new site user from command line.

    :param request:
    :param username:
    :param email:
    :param password:
    :param source:
    :param admin: Set this user to admin. The first user is always implicitly admin.
    :return:
    """
    User = get_user_class(request.registry)
    dbsession = request.dbsession
    u = dbsession.query(User).filter_by(email=email).first()
    if u is not None:
        return u

    u = User(email=email, username=username)
    dbsession.add(u)
    dbsession.flush()  # Make sure u.user_data is set

    if password:
        user_registry = get_user_registry(request)
        user_registry.set_password(u, password)

    u.registration_source = source
    u.activated_at = now()

    request.registry.notify(UserCreated(request, u))

    if admin:
        group = dbsession.query(Group).filter_by(name="admin").one_or_none()
        group.users.append(u)

    return u
Example #33
0
def get_or_create_user(request, email, password):
    User = get_user_class(request.registry)
    dbsession = request.dbsession

    u = dbsession.query(User).filter_by(email=email).first()
    if u is not None:
        return u

    u = User(email=email, username=email)
    dbsession.add(u)
    dbsession.flush()  # Make sure u.user_data is set

    if password:
        user_registry = get_user_registry(request)
        user_registry.set_password(u, password)

    u.registration_source = "command_line"
    u.activated_at = now()

    request.registry.notify(UserCreated(request, u))

    return u
Example #34
0
    def authenticate_user(self,
                          user: IUser,
                          login_source: str,
                          location: str = None):
        """Make the current session logged in session for this particular user."""
        request = self.request
        settings = request.registry.settings

        require_activation = asbool(
            settings.get('horus.require_activation', True))
        allow_inactive_login = asbool(
            settings.get('horus.allow_inactive_login', False))

        if (not allow_inactive_login) and require_activation and (
                not user.is_activated()):
            raise AuthenticationFailure(
                'Your account is not active, please check your e-mail. If your account activation email as expired please request a password reset.'
            )

        if not user.can_login():
            raise AuthenticationFailure(
                'This user account cannot log in at the moment.')

        user_registry = get_user_registry(request)
        token = user_registry.get_session_token(user)
        headers = remember(request, token)
        # assert headers, "Authentication backend did not give us any session headers"

        if not location:
            location = get_config_route(request, 'horus.login_redirect')

        self.greet_user(user)

        self.update_login_data(user)

        e = events.Login(request, user)
        request.registry.notify(e)

        return HTTPFound(location=location, headers=headers)
Example #35
0
def resolve_principals(session_token: str, request: Request) -> Optional[List[str]]:
    """Get applied groups and other for the user.

    This is a callback for :py:class:`pyramid.authentication.SessionAuthenticationPolicy`.

    * List all groups as ``group:admin`` style strings

    * List super user as ``superuser:superuser`` style string
    """

    # TODO: Abstract this to its own service like in Warehouse?
    user_registry = get_user_registry(request)
    user = user_registry.get_user_by_session_token(session_token)
    if not user:
        return None

    settings = request.registry.settings

    # Read superuser names from the config
    superusers = aslist(settings.get("websauna.superusers"))

    admin_as_superuser = asbool(settings.get("websauna.admin_as_superuser", False))

    if user_registry.can_login(user):

        principals = ['group:{}'.format(g.name) for g in user_registry.get_groups(user)]

        # Allow superuser permission
        if user.username in superusers or user.email in superusers:
            # Superuser explicitly listed in the configuration
            principals.append("superuser:superuser")
        elif admin_as_superuser and ("group:admin" in principals):
            # Automatically promote admins to superusers when doing local development
            principals.append("superuser:superuser")

        return principals

    # User not found, user disabled
    return None
Example #36
0
    def reset_password(self,
                       activation_code: str,
                       password: str,
                       location: str = None) -> Response:
        """Perform actual password reset operations.

        User has following password reset link (GET) or enters the code on a form.

        :param activation_code: Activation code provided by the user.
        :param password: New user password.
        :param location: URL to redirect the user after the password request.
        :return: Redirect to location.
        :raise: HTTPNotFound if activation_code is not found.
        """
        request = self.request
        user_registry = get_user_registry(request)
        user = user_registry.get_user_by_password_reset_token(activation_code)
        if not user:
            return HTTPNotFound("Activation code not found")

        user_registry.reset_password(user, password)

        messages.add(
            request,
            msg=
            "The password reset complete. Please sign in with your new password.",
            kind='success',
            msg_id="msg-password-reset-complete")

        request.registry.notify(
            PasswordResetEvent(self.request, user, password))
        request.registry.notify(
            UserAuthSensitiveOperation(self.request, user, "password_reset"),
            request)

        location = location or get_config_route(
            request, 'websauna.reset_password_redirect')
        return HTTPFound(location=location)
Example #37
0
def main(argv=sys.argv):

    if len(argv) < 3:
        usage(argv)

    config_uri = argv[1]
    request = init_websauna(config_uri)

    User = get_user_class(request.registry)
    dbsession = request.dbsession

    if len(argv) == 4:
        password = argv[3]
    else:
        password = getpass.getpass("Password:"******"Password (again):")

        if password != password2:
            sys.exit("Password did not match")

    with transaction.manager:

        u = User(email=argv[2], username=argv[2])

        if password:
            user_registry = get_user_registry(request)
            user_registry.set_password(u, password)

        u.registration_source = "command_line"
        u.activated_at = now()
        dbsession.add(u)
        dbsession.flush()

        request.registry.notify(UserCreated(request, u))

        print("Created user #{}: {}, admin: {}".format(u.id, u.email,
                                                       u.is_admin()))
Example #38
0
def main(argv=sys.argv):

    if len(argv) < 3:
        usage(argv)

    config_uri = argv[1]
    request = init_websauna(config_uri)

    User = get_user_class(request.registry)
    dbsession = request.dbsession

    if len(argv) == 4:
        password = argv[3]
    else:
        password = getpass.getpass("Password:"******"Password (again):")

        if password != password2:
            sys.exit("Password did not match")

    with transaction.manager:

        u = User(email=argv[2], username=argv[2])

        if password:
            user_registry = get_user_registry(request)
            user_registry.set_password(u, password)

        u.registration_source = "command_line"
        u.activated_at = now()
        dbsession.add(u)
        dbsession.flush()

        request.registry.notify(UserCreated(request, u))

        print("Created user #{}: {}, admin: {}".format(u.id, u.email, u.is_admin()))