Exemple #1
0
 def sign_timed_value(cls, value_string, timestamp_string):
     timed_value = cls.get_delimited_encoded_string(value_string,
                                                    timestamp_string)
     key = ExecutionContext.get_context().config.web.csrf_key
     return hmac.new(key.encode('utf-8'),
                     msg=timed_value.encode('utf-8'),
                     digestmod=hashlib.sha1).hexdigest()
Exemple #2
0
 def secure_cookie_is_valid(self):
     context = ExecutionContext.get_context()
     try:
         salt = context.request.cookies[context.config.web.secure_key_name]
         return self.secure_salt == salt
     except KeyError:
         return False
Exemple #3
0
    def assemble(self, login_bookmark=None, get_queues=None):
        self.get_queues = get_queues
        self.web_session = ExecutionContext.get_context().session
        self.first_log_in = ViewPreCondition(
            LoginSession.for_current_session().is_logged_in,
            exception=Detour(login_bookmark))

        self.workflow_interface = WorkflowInterface()
        self.inbox = Inbox(self.get_queues())

        inbox_view_factory = self.define_view('/', title=_('Inbox'))
        inbox_view_factory.set_slot('main_slot',
                                    InboxWidget.factory(self.inbox))

        task_view_factory = self.define_view('/task',
                                             view_class=TaskView,
                                             task=PersistedField(
                                                 Task, required=True))
        task_view_factory.add_precondition(self.first_log_in)
        inbox_view_factory.add_precondition(self.first_log_in)

        self.define_transition(self.workflow_interface.events.take_task,
                               inbox_view_factory, task_view_factory)
        self.define_transition(self.workflow_interface.events.go_to_task,
                               inbox_view_factory, task_view_factory)
        self.define_transition(self.workflow_interface.events.defer_task,
                               task_view_factory, inbox_view_factory)
        self.define_transition(self.workflow_interface.events.release_task,
                               task_view_factory, inbox_view_factory)
Exemple #4
0
def test_login_queries(party_account_fixture, web_fixture):
    """"""
    context = ExecutionContext.get_context()

    config = context.config
    user_session = context.session
    login_session = LoginSession.for_session(context.session)
    system_account = party_account_fixture.system_account

    web_fixture.request.scheme = 'https'
    context.request.cookies[
        config.web.secure_key_name] = user_session.secure_salt
    assert config.web.idle_secure_lifetime < config.web.idle_lifetime
    assert config.web.idle_lifetime < config.web.idle_lifetime_max

    # Case: user logs in
    user_session.last_activity = None
    login_session.set_as_logged_in(system_account, False)
    assert login_session.is_logged_in()
    assert login_session.is_logged_in(secured=True)

    # Case: user logs out
    login_session.log_out()
    assert not login_session.is_logged_in()
    assert not login_session.is_logged_in(secured=True)

    # Case: user activity is older than secure lifetime
    assert (config.web.idle_lifetime - config.web.idle_secure_lifetime) > 50
    login_session.set_as_logged_in(system_account, False)
    user_session.last_activity = datetime.now() - timedelta(
        seconds=config.web.idle_secure_lifetime + 50)
    assert login_session.is_logged_in()
    assert not login_session.is_logged_in(secured=True)

    # Case: user activity is older than all lifetimes
    assert (config.web.idle_lifetime - config.web.idle_secure_lifetime) > 50
    login_session.set_as_logged_in(system_account, False)
    user_session.last_activity = datetime.now() - timedelta(
        seconds=config.web.idle_lifetime + 50)
    assert not login_session.is_logged_in()
    assert not login_session.is_logged_in(secured=True)

    # Case: user activity is older than non-secure lifetime, but keep_me_logged_in is set
    assert (config.web.idle_lifetime - config.web.idle_secure_lifetime) > 50
    assert (config.web.idle_lifetime_max - config.web.idle_lifetime) > 50
    login_session.set_as_logged_in(system_account, True)
    user_session.last_activity = datetime.now() - timedelta(
        seconds=config.web.idle_lifetime + 50)
    assert login_session.is_logged_in()
    assert not login_session.is_logged_in(secured=True)

    # Case: user activity is older than non-secure lifetime max, but keep_me_logged_in is set
    assert (config.web.idle_lifetime - config.web.idle_secure_lifetime) > 50
    assert (config.web.idle_lifetime_max - config.web.idle_lifetime) > 50
    login_session.set_as_logged_in(system_account, True)
    Session.flush()
    user_session.last_activity = datetime.now() - timedelta(
        seconds=config.web.idle_lifetime_max + 50)
    assert not login_session.is_logged_in()
    assert not login_session.is_logged_in(secured=True)
 def handle_request(self, request):
     context = ExecutionContext.get_context()
     assert context.session is UserSessionStub.session  # By the time user code executes, the session is set
     assert monitor.times_called == 1  # The database has been committed before user code started executing
     assert context.session.last_activity_time_set
     assert not UserSessionStub.session.key_is_set
     return Response()
Exemple #6
0
 def start_thread(self):
     assert not self.running
     self.running = True
     self.httpd_thread = Thread(target=functools.partial(
         self.main_loop, ExecutionContext.get_context()))
     self.httpd_thread.daemon = True
     self.httpd_thread.start()
Exemple #7
0
 def filesystem_path(self, relative_path):
     context = ExecutionContext.get_context()
     static_root = context.config.web.static_root
     if relative_path.endswith('/'):
         relative_path += 'index.d.html'
     return self.i18nise_filename(
         os.path.join(static_root, *relative_path.split('/')))
Exemple #8
0
 def get_widget_class_for(self, task):
     config = ExecutionContext.get_context().config
     for widget_class in config.workflowui.task_widgets:
         if issubclass(widget_class,
                       TaskWidget) and widget_class.displays(task):
             return widget_class
     raise ProgrammerError('no Widget found to display %s' % task)
Exemple #9
0
 def save_for(cls, view, form=None, **kwargs):
     assert (not form) or (form.view is view)
     channel_name = form.channel_name if form else None
     web_session = ExecutionContext.get_context().session
     instance = cls(web_session=web_session, view_path=view.full_path, ui_name=view.user_interface.name, channel_name=channel_name, **kwargs)
     Session.add(instance)
     return instance
Exemple #10
0
 def set_session_key(self, response):
     context = ExecutionContext.get_context()
     session_cookie = self.as_key()
     response.set_cookie(context.config.web.session_key_name, urllib.parse.quote(session_cookie), path='/', samesite='Strict')
     if self.is_secured():
         response.set_cookie(context.config.web.secure_key_name, urllib.parse.quote(self.secure_salt), secure=True, path='/',
                             max_age=context.config.web.idle_secure_lifetime, samesite='Strict')
Exemple #11
0
 def get_session_key(cls):
     context = ExecutionContext.get_context()
     try:
         raw_cookie = context.request.cookies[context.config.web.session_key_name]
         return urllib.parse.unquote(raw_cookie)
     except KeyError:
         return None
Exemple #12
0
 def clear_all_view_data(cls, view):
     web_session = ExecutionContext.get_context().session
     items = Session.query(cls).filter_by(web_session=web_session,
                                          view_path=view.full_path,
                                          ui_name=view.user_interface.name)
     for stale in items:
         Session.delete(stale)
Exemple #13
0
 def replace_elixir(self):
     # reahl-declarative is new, and replaces reahl-elixir-impl
     orm_control = ExecutionContext.get_context().system_control.orm_control
     self.schedule('cleanup',
                   orm_control.remove_schema_version_for,
                   egg_name='reahl-web-elixirimpl',
                   fail_if_not_found=False)
Exemple #14
0
 def find_for(cls, view, form=None):
     assert (not form) or (form.view is view)
     web_session = ExecutionContext.get_context().session
     channel_name = form.channel_name if form else None
     return Session.query(cls).filter_by(web_session=web_session,
                                         view_path=view.full_path,
                                         ui_name=view.user_interface.name,
                                         channel_name=channel_name)
Exemple #15
0
 def i18nise_filename(self, for_default_locale):
     current_locale = ExecutionContext.get_context().interface_locale
     head, tail = os.path.splitext(for_default_locale)
     head, d = os.path.splitext(head)
     for_current_locale = head+'.%s' % current_locale+d+tail
     if os.path.isfile(for_current_locale):
         return for_current_locale
     return for_default_locale
Exemple #16
0
 def is_expired(self):
     now = self.get_now()
     csrf_timeout_seconds = ExecutionContext.get_context(
     ).config.web.csrf_timeout_seconds
     cutoff_timestamp = (
         now -
         datetime.timedelta(seconds=csrf_timeout_seconds)).timestamp()
     return self.timestamp < cutoff_timestamp
Exemple #17
0
 def __init__(self, system_account, new_email):
     requirements = [VerifyEmailRequest(email=new_email,
                                        subject_config='accounts.email_change_subject',
                                        email_config='accounts.email_change_email')]
     config = ExecutionContext.get_context().config
     deadline = datetime.now() + timedelta(days=config.accounts.request_verification_timeout)
     self.system_account = system_account
     super(ChangeAccountEmail, self).__init__(requirements=requirements,
                                              deadline=deadline)
Exemple #18
0
 def send_mail(self, destination, subject_config_key, mail_config_key):
     data = self.get_data_for_substitution()
     config = ExecutionContext.get_context().config
     admin_email = config.accounts.admin_email
     subject = Template(config.get_from_string(subject_config_key)).safe_substitute(data)
     message_text = Template(config.get_from_string(mail_config_key)).safe_substitute(data)
     message = MailMessage(admin_email, [destination], subject, message_text) 
     mailer = config.accounts.mailer_class.from_context()
     mailer.send_message(message)
Exemple #19
0
 def set_csrf_token_in_rendered_form_to_expired(self, browser):
     valid_token = self.get_csrf_token_in_rendered_form(browser)
     reconstructed_token = CSRFToken.from_coded_string(valid_token)
     allowed_timeout = ExecutionContext.get_context(
     ).config.web.csrf_timeout_seconds
     now = datetime.datetime.now(tz=datetime.timezone.utc)
     stale_time = now - datetime.timedelta(seconds=allowed_timeout + 1)
     reconstructed_token.timestamp = stale_time.timestamp()
     stale_token_string = reconstructed_token.as_signed_string()
     self.set_csrf_token_in_rendered_form(browser, stale_token_string)
Exemple #20
0
 def replace_elixir(self):
     # reahl-declarative is new, and replaces reahl-elixir-impl
     orm_control = ExecutionContext.get_context().system_control.orm_control
     self.schedule('cleanup',
                   orm_control.initialise_schema_version_for,
                   egg_name='reahl-web-declarative',
                   egg_version=self.version)
     self.schedule('cleanup',
                   orm_control.remove_schema_version_for,
                   egg_name='reahl-web-elixirimpl')
Exemple #21
0
 def start_thread(self):
     assert not self.running
     self.running = True
     try:
         context = ExecutionContext.get_context()
     except NoContextFound:
         context = None
     self.httpd_thread = Thread(target=functools.partial(self.main_loop, context))
     self.httpd_thread.daemon = True
     self.httpd_thread.start()
    def __init__(self, view):
        super(AddressBookPanel, self).__init__(view)

        config = ExecutionContext.get_context().config
        if config.componentconfig.showheader:
            self.add_child(H(view, 1, text='Addresses'))

        for address in Session.query(Address).all():
            self.add_child(AddressBox(view, address))

        self.add_child(AddAddressForm(view))
Exemple #23
0
    def get_interface_locale(self):
        context = ExecutionContext.get_context()
        if not hasattr(context, 'request'):
            return 'en_gb'

        url = Url.get_current_url()
        possible_locale, path = url.get_locale_split_path()
        supported_locales = ReahlEgg.get_languages_supported_by_all(context.config.reahlsystem.root_egg)
        if possible_locale:
            if possible_locale in supported_locales:
                return possible_locale
        return context.config.web.default_url_locale
Exemple #24
0
    def __init__(self, view, account_management_interface, verify_bookmark):
        super().__init__(view)
        config = ExecutionContext.get_context().config
        self.add_child(
            P(view,
              text=_('There is a registration pending for email address "%s".')
              % account_management_interface.email))
        self.add_child(
            P(view,
              text=_(
                  'Before you can log in, you need to verify your email address using the secret key '
                  'sent to that address. It looks like you did not do that.')))
        self.add_child(
            P(view,
              text=
              _('You should receive the automated email anything between a minute to an hour after '
                'registration. Sometimes though, your email software may mistakenly identify our '
                'email as junk email. If this happens it will be hidden away in a "junk email" '
                'folder or just not shown to you.')))
        self.add_child(
            P(view,
              text=
              _('You can have the email re-sent to you by clicking on the button below.'
                )))
        self.add_child(
            P(view,
              text=
              _('Before you do that, however, please make sure that your email system will allow '
                'emails from "%s" through to you.') %
              config.accounts.admin_email))
        self.add_child(
            P(view,
              text=
              _('Sometimes these emails arrive immediately, but they may also be delayed.'
                )))
        p = P(
            view,
            text=
            _('Once you located the email, retrieve the code and then enter it on {verify}.'
              ))
        self.add_child(
            p.format(verify=A.from_bookmark(
                view,
                verify_bookmark.with_description(_('the verification page')))))

        self.add_child(RegistrationPendingForm(view))
Exemple #25
0
    def __get__(self, obj, objtype):
        setting_name = self.name(type(obj))
        if self.is_localised(obj):
            context = ExecutionContext.get_context()
            locale = context.interface_locale if context else ''
            try:
                return obj.__dict__['%s_%s' % (setting_name, locale)]
            except KeyError:
                pass

        if self.is_set(obj):
            return obj.__dict__[setting_name]

        if self.defaulted:
            return self.default_value_for_configuration(obj)

        raise ConfigurationException('%s was not set' % setting_name)
Exemple #26
0
    def is_applicable(cls, current_schema_version, new_version):
        if super().is_applicable(current_schema_version, new_version):
            # reahl-declarative is new, and replaces reahl-elixir-impl. Therefore it thinks it is migrating from version 0 always.
            # We need to manually check that it's not coming from reahl-web-elixirimpl 2.0 or 2.1 instead.
            orm_control = ExecutionContext.get_context(
            ).system_control.orm_control

            class FakeElixirEgg:
                name = 'reahl-web-declarative'

            previous_elixir_version = orm_control.schema_version_for(
                FakeElixirEgg(), default='0.0')

            return previous_elixir_version != '0.0' and super().is_applicable(
                current_schema_version, previous_elixir_version)
        else:
            return False
Exemple #27
0
    def finalise_session(self):
        nested = Session().transaction.nested
        if nested:
            # This is necessary to facilitate testing.  When testing, code continually
            # runs in a nested transaction inside a real transaction which will both
            # eventually be rolled back.  This is done so that this method can use the
            # nested state of the transaction to detect that it is called during a test.
            # If called during a test, this method should NOT commit, and it should NOT
            # nnuke the session
            return

        self.commit()

        context = ExecutionContext.get_context()
        if context.system_control.db_control.is_in_memory:
            Session.expunge_all()
        else:
            Session.remove()
Exemple #28
0
    def with_languages(self):
        """Populates this Menu with a MenuItem for each available language.

           Answers the same Menu.

           .. versionadded:: 3.2
        """
        context = ExecutionContext.get_context()
        supported_locales = ReahlEgg.get_languages_supported_by_all(
            context.config.reahlsystem.root_egg)
        for locale in supported_locales:
            try:
                language_name = Locale.parse(locale).display_name
            except UnknownLocaleError:
                language_name = locale

            bookmark = self.view.as_bookmark(description=language_name,
                                             locale=locale)
            bookmark.exact = True
            self.add_bookmark(bookmark)
        return self
Exemple #29
0
 def send_mail(self, destination, subject_config_key, mail_config_key):
     data = self.get_data_for_substitution()
     config = ExecutionContext.get_context().config
     admin_email = config.accounts.admin_email
     subject = Template(
         config.get_from_string(subject_config_key)).safe_substitute(data)
     message_text = Template(
         config.get_from_string(mail_config_key)).safe_substitute(data)
     message = MailMessage(admin_email, [destination], subject,
                           message_text)
     mailer = config.accounts.mailer_class.from_context()
     try:
         mailer.send_message(message)
     except ConnectionError as e:
         message = _(
             'Could not send registration verification email message to %s: %s.'
         ) % (self.email, str(e))
         user_message = message + _(
             ' Please contact the site administrator and try again later.')
         logging.getLogger(__name__).error(message)
         raise DomainException(message=user_message)
Exemple #30
0
 def from_context(cls):
     """Returns a Mailer, using the system configuration."""
     config = ExecutionContext.get_context().config
     smtp_host = config.mail.smtp_host
     smtp_port = config.mail.smtp_port
     smtp_user = config.mail.smtp_user
     smtp_password = config.mail.smtp_password
     smtp_use_initial_encrypted_connection = config.mail.smtp_use_initial_encrypted_connection
     smtp_upgrade_initial_connection_to_encrypted = config.mail.smtp_upgrade_initial_connection_to_encrypted
     smtp_keyfile = config.mail.smtp_keyfile
     smtp_certfile = config.mail.smtp_certfile
     return cls(smtp_host=smtp_host,
                smtp_port=smtp_port,
                smtp_user=smtp_user,
                smtp_password=smtp_password,
                smtp_use_initial_encrypted_connection=
                smtp_use_initial_encrypted_connection,
                smtp_upgrade_initial_connection_to_encrypted=
                smtp_upgrade_initial_connection_to_encrypted,
                smtp_keyfile=smtp_keyfile,
                smtp_certfile=smtp_certfile)