Beispiel #1
0
    def execution_context_stacking(self, fixture):
        """When an ExecutionContext overrides a deeper one on the call stack, it will retain the same id."""
        some_context = ExecutionContext()

        vassert(some_context is not fixture.context)
        vassert(some_context.id == fixture.context.id)

        with some_context:
            vassert(ExecutionContext.get_context_id() == some_context.id)
Beispiel #2
0
 def new_context(self, config=None, session=None):
     context = ExecutionContext()
     context.set_config(config or self.config)
     context.set_system_control(self.system_control)
     with context:
         context.set_session(session or self.session)
     return context
Beispiel #3
0
def test_contents():
    """A Session, Config or SystemControl may be set on the ExecutionContext."""
    some_context = ExecutionContext()

    session = EmptyStub()
    config = EmptyStub()
    system_control = EmptyStub()

    some_context.session = session
    some_context.config = config
    some_context.system_control = system_control

    assert some_context.session is session
    assert some_context.config is config
    assert some_context.system_control is system_control
Beispiel #4
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)
Beispiel #5
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()
Beispiel #6
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)
Beispiel #7
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()
Beispiel #8
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)
Beispiel #9
0
def test_namespaces():
    ExecutionContext().install()
    state_dict = {}
    a = Field()
    a.bind('x', a)

    # Case: namespaces change the name of the Field
    b = a.in_namespace('deeper')

    assert a.name == 'x'
    assert b.name == 'deeper-x'

    # Case: namespaces can be nested
    c = b.in_namespace('even')
    assert c.name == 'even-deeper-x'

    # Case: a Field *in* different namespace, but made from another share the same data
    a.initial_value = EmptyStub()
    a.input_status = EmptyStub()
    a.validation_error = EmptyStub()
    a.user_input = EmptyStub()
    a.parsed_input = EmptyStub()

    assert a.initial_value is b.initial_value is c.initial_value
    assert a.input_status is b.input_status is c.input_status
    assert a.validation_error is b.validation_error is c.validation_error
    assert a.user_input is b.user_input is c.user_input
    assert a.parsed_input is b.parsed_input is c.parsed_input
Beispiel #10
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)
Beispiel #11
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)
Beispiel #12
0
def test_reahl_additions():
    ExecutionContext().install()

    try:
        metadata.bind = 'sqlite:///:memory:'
        metadata.create_all()

        address = Address()
        Session.add(address)
        email_field = address.fields.email_address

        # While a programmer would not usually write code like this,
        # it is useful to show how the framework can use Fields and Events
        # to obtain more information about a certain Field/Event:
        assert email_field.label == 'Email'

        # Fields are used (amongst other things) to validate user input:
        with expected(Exception):
            email_field.from_input('invalid email address')

        with expected(NoException):
            assert address.email_address == None
            email_field.from_input('*****@*****.**')
            assert address.email_address == '*****@*****.**'

        # After input was given, the field is set on the object it belongs to:
        # (The value set is a marshalled version of the user input. In this case it is just
        #  a string again, but it could have been, for example an EmailAddress object,
        #  and Integer, or a Date.)
        assert address.email_address == '*****@*****.**'

    finally:
        metadata.bind = None
Beispiel #13
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
Beispiel #14
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('/')))
Beispiel #15
0
 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()
Beispiel #16
0
def test_global_state():
    """A Field can store its data in a global dict so that it can be recreated later with the same underlying data."""
    ExecutionContext().install()
    state_dict = {}
    a = Field()
    a.bind('x', a)

    a.input_status = EmptyStub()
    a.validation_error = EmptyStub()
    a.user_input = EmptyStub()
    a.parsed_input = EmptyStub()

    a.activate_global_field_data_store(state_dict)

    a.initial_value = EmptyStub()

    b = Field()
    b.bind('x', b)

    assert a.initial_value is not b.initial_value
    assert a.input_status is not b.input_status
    assert a.validation_error is not b.validation_error
    assert a.user_input is not b.user_input
    assert a.parsed_input is not b.parsed_input

    b.activate_global_field_data_store(state_dict)

    assert a.initial_value is b.initial_value
    assert a.input_status is b.input_status
    assert a.validation_error is b.validation_error
    assert a.user_input is b.user_input
    assert a.parsed_input is b.parsed_input
Beispiel #17
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
Beispiel #18
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')
Beispiel #19
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
Beispiel #20
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
Beispiel #21
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
Beispiel #22
0
 def create_context(self, config_directory):
     try:
         self.context = ExecutionContext.for_config_directory(config_directory)
     except DistributionNotFound as ex:
         ex.args = ('%s (In development? Did you forget to do a "reahl setup -- develop -N"?)' % ex.args[0],)
         raise
     self.context.install()
     self.context.system_control = SystemControl(self.context.config)
Beispiel #23
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)
Beispiel #24
0
class ListConfig(ProductionCommand):
    """Lists current configuration settings."""
    keyword = 'listconfig'

    def assemble(self):
        super().assemble()
        self.parser.add_argument('-v', '--values', action='store_true', dest='print_values', help='prints the currently configured value')
        self.parser.add_argument('-f', '--files', action='store_true', dest='print_files', help='prints the filename where the setting should be defined')
        self.parser.add_argument('-d', '--defaults', action='store_true', dest='print_defaults', help='prints the default value')
        self.parser.add_argument('-m', '--missing', action='store_true', dest='print_missing_only', help='prints the missing values only')
        self.parser.add_argument('-i', '--info', action='store_true', dest='print_description', help='prints a description')

    def create_context(self, config_directory):
        self.context = ExecutionContext(name=self.__class__.__name__)

    def execute(self, args):
        super().execute(args)
        self.context.install()

        print('Listing config for %s' % self.directory)
        config = StoredConfiguration(self.directory)
        config.configure(validate=False)
        for config_file, key, value, setting in config.list_all():
            to_print = '%-35s' % key
            if args.print_files:
                to_print += '\t%s' % config_file
            if args.print_values:
                to_print += '\t%s' % value
            if args.print_defaults:
                if setting.defaulted:
                    message = str(setting.default)
                    if setting.dangerous:
                        message += ' (DANGEROUS DEFAULT)'
                elif setting.automatic:
                    message = 'AUTOMATIC'
                else:
                    message = 'NO DEFAULT'
                to_print += '\t%s' % message
            if args.print_description:
                to_print += '\t%s' % setting.description

            if args.print_missing_only and not isinstance(value, MissingValue):
                pass
            else:
                print(to_print)
Beispiel #25
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)
Beispiel #26
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)
Beispiel #27
0
def reahl_scope():
    try:
        return ExecutionContext.get_context_id()
    except NoContextFound:
        message = 'Database code can normally only be executed by code executed as part of handling a Request.'
        message += ' Such code is then executed within the context of, for example, a database transaction.'
        message += ' Looks like you attempted to execute database code from the wrong place, since no such context'
        message += ' could be found.'
        raise ProgrammerError(message)
Beispiel #28
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)
Beispiel #29
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')
Beispiel #30
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()