def activate_instance(request):
    token = request.GET.get("token", "")

    try:
        encrypted_data = token.encode(
            "ascii"
        )  # encrypted json containing the game id, the user login and a validity timestamp
        (game_instance_id, creator_login,
         creator_email) = decode_game_activation_token(encrypted_data)

        if not datamanager_administrator.game_instance_exists(
                game_instance_id):
            datamanager_administrator.create_game_instance(
                game_instance_id=game_instance_id,
                creator_login=creator_login,
                creator_email=creator_email,
                skip_randomizations=False)
        else:
            metadata = datamanager_administrator.get_game_instance_metadata_copy(
                game_instance_id)  # shall NOT raise errors
            if (metadata["creator_login"] != creator_login
                    or metadata["creator_email"] != creator_email):
                raise ValueError(
                    "Creator data doesn't match for game instance %(game_instance_id)s"
                    % SDICT(game_instance_id=game_instance_id))

        # we retrieve the datamanager whatever its possible maintenance status
        dm = datamanager_administrator.retrieve_game_instance(
            game_instance_id,
            request=None,
            metadata_checker=lambda *args, **kwargs: True)
        master_login = dm.get_global_parameter("master_login")

        authentication_token = authentication.compute_enforced_login_token(
            game_instance_id=game_instance_id,
            login=master_login,
            is_observer=False)
        session_token_display = urlencode({
            authentication.ENFORCED_SESSION_TICKET_NAME:
            authentication_token
        })

        import pychronia_game.views
        target_url = config.SITE_DOMAIN + reverse(
            pychronia_game.views.homepage,
            kwargs=dict(game_instance_id=game_instance_id,
                        game_username=master_login))
        target_url += "?" + session_token_display

        content = _(
            "In case you don't get properly redirected, please copy this link into our URL bar: %(target_url)s"
        ) % SDICT(target_url=target_url)
        return HttpResponseRedirect(target_url, content=content)

    except (ValueError, TypeError, LookupError, AttributeError,
            UnicodeError) as e:
        logging.warning("Game activation key not recognized : %s",
                        token,
                        exc_info=True)
        return HttpResponseForbidden(_("Activation key not recognized"))
예제 #2
0
    def request(self, **request_args):
        """Constructs a generic request object, INCLUDING middleware modifications."""

        from django.core import urlresolvers

        request = RequestFactory.request(self, **request_args)
        ###pprint.pprint(request)

        utilities.make_request_querydicts_mutable(request)

        request.session = DJANGO_TEST_CLIENT.session  # hack

        # we mimick django authentication middleware
        from django.contrib.auth.models import AnonymousUser
        request.user = AnonymousUser()  # default

        # we mimick messages middleware
        from django.contrib.messages.storage import default_storage
        request._messages = default_storage(request)

        # we mimick ZODB middleware
        datamanager = retrieve_game_instance(
            game_instance_id=TEST_GAME_INSTANCE_ID,
            request=request,
            update_timestamp=False)
        request.datamanager = datamanager  # for template tags and the likes
        """ Old version, before Django2.0 middlewares

            handler = BaseHandler()

            handler.load_middleware()

            for middleware_method in handler._request_middleware:
                #print("APPLYING REQUEST MIDDLEWARE ", middleware_method, file=sys.stderr)
                if middleware_method(request):
                    raise Exception("Couldn't create request mock object - "
                                    "request middleware returned a response")

            urlconf = settings.ROOT_URLCONF
            urlresolvers.set_urlconf(urlconf)
            resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)

            callback, callback_args, callback_kwargs = resolver.resolve(
                request.path_info)

            # Apply view middleware
            for middleware_method in handler._view_middleware:
                #print("APPLYING VIEW MIDDLEWARE ", middleware_method, file=sys.stderr)
                response = middleware_method(request, callback, callback_args, callback_kwargs)
                if response:
                    raise Exception("Couldn't create request mock object - "
                                    "view middleware returned a response")
        """

        return request
예제 #3
0
def execute():
    result = True
    idx = 0
    for idx, metadata in enumerate(get_all_instances_metadata(), start=1):
        instance_id = metadata["instance_id"]
        dm = retrieve_game_instance(instance_id)
        try:
            dm.check_database_coherence()  # NO strict mode enforced
        except Exception as e:
            result = False
            logging.critical("Error during checking of game instance '%s'",
                             instance_id,
                             exc_info=True)
        else:
            logging.info("Game instance '%s' is OK", instance_id)
    return (idx, result)
예제 #4
0
def execute():
    instance_id = sys.argv[1]  # please provide game instance id on cmd line
    dm = retrieve_game_instance(instance_id)

    msgs = dm.get_all_dispatched_messages()

    tpls = [dm.convert_msg_to_template(msg) for msg in msgs]
    #pprint.pprint(tpls)

    yaml_str = utilities.dump_data_tree_to_yaml(tpls,
                                                default_style=">",
                                                width=100)
    yaml_str = yaml_str.replace("\n-", "\n\n\n-")  # separate atomic templates

    output_file = "%s_extracted_message_templates.yaml" % instance_id
    utilities.write_to_file(output_file, content=yaml_str)

    #print(data)
    print((">> Extract file %s successfully created" % output_file))
예제 #5
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        # on exception : normal 500 handling takes place

        assert hasattr(
            request, 'session'
        ), "The game authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."

        request.process_view = None  # GameView instance will attach itself here on execution

        if __debug__: request.start_time = time.time()

        if "game_instance_id" in view_kwargs:
            # TOFIX select the proper subtree of ZODB
            # Manage possible errors of wrong game_id !
            ##request.game_instance_id = view_kwargs["game_instance_id"]
            game_instance_id = view_kwargs["game_instance_id"]
            del view_kwargs["game_instance_id"]

            try:
                update_timestamp = (
                    request.method == "POST"
                )  # we consider that other accesses are not meaningful
                # by default, this checks that game is not in maintenance
                request.datamanager = retrieve_game_instance(
                    game_instance_id=game_instance_id,
                    request=request,
                    update_timestamp=update_timestamp)
            except GameMaintenanceError as e:
                # TODO - better handling of 503 code, with dedicated template #
                return HttpResponse(content=str(e) + "<br/>" +
                                    _("Please come back later."),
                                    status=503)
            except UsageError:
                raise Http404  # unexisting instance

            if not request.datamanager.is_initialized:
                raise RuntimeError(
                    "ZodbTransactionMiddleware - Game data isn't in initialized state"
                )

            return None
예제 #6
0
    def setUp(self):

        assert settings.DEBUG == True

        django.utils.translation.activate(
            "en")  # to test for error messages, just in case...

        reset_zodb_structure()

        yaml_fixture = None
        skip_initializations = False
        if BaseGameTestCase.SHARED_DM_INITIAL_DATA_TREE:
            print(
                "[UNIT-TESTS] Using SHARED_DM_INITIAL_DATA_TREE to speed up the DM creation"
            )
            yaml_fixture = copy.deepcopy(
                BaseGameTestCase.SHARED_DM_INITIAL_DATA_TREE)
            skip_initializations = True

        # FIXME - very heavy with loading + checking, we should do it only once and copy/paste dm.data tree.
        create_game_instance(
            game_instance_id=TEST_GAME_INSTANCE_ID,
            creator_login="******",
            skip_randomizations=True,  # handy to test stuffs
            skip_initializations=skip_initializations,
            skip_coherence_check=True,
            yaml_fixture=yaml_fixture)

        if not BaseGameTestCase.SHARED_DM_INITIAL_DATA_TREE:
            # we cache the FIRST datamanager data, for reuse
            initial_dm = retrieve_game_instance(
                game_instance_id=TEST_GAME_INSTANCE_ID)
            BaseGameTestCase.SHARED_DM_INITIAL_DATA_TREE = copy.deepcopy(
                initial_dm.data)

        try:

            test_http_host = "localhost:80"

            self.client = DJANGO_TEST_CLIENT

            self.request_factory = RequestMock(HTTP_HOST=test_http_host,
                                               session=self.client.session)

            request = self.request_factory.get(HOME_URL)
            # this request is empty, not gone through middlewares!
            assert request.datamanager
            assert request.session
            assert request.session is not self.client.session, \
                (request.session, self.client.session) # generated on demand
            assert request.user.is_anonymous
            self.request = request

            self.dm = self.request.datamanager

            assert self.dm.is_initialized
            assert self.dm.connection

            self.dm.clear_all_event_stats()
            if not skip_initializations:
                self.dm.check_database_coherence(
                )  # thus, only done for the first testcase
                assert self.dm.get_event_count(
                    "BASE_CHECK_DB_COHERENCE_PUBLIC_CALLED"
                ) == 1  # no bypassing because of wrong override

            self.dm.set_game_state(True)
            self.dm.set_activated_game_views(
                list(self.dm.get_activable_views().keys())
            )  # QUICK ACCESS FIXTURE

            self.dm.clear_all_event_stats()

            #self.default_player = self.dm.get_character_usernames()[0]
            #self._set_user(self.TEST_LOGIN)

            self.initial_msg_sent_length = len(
                self.dm.get_all_dispatched_messages())
            self.initial_msg_queue_length = len(
                self.dm.get_all_queued_messages())

            # comment this to have eclipse's autocompletion to work for datamanager anyway
            self.dm = AutoCheckingDM(
                self.dm)  # protection against uncommitted, pending changes
            assert object.__getattribute__(
                self.dm, "_real_dm") == self.request.datamanager  # WRAPPED

            # NO NEED TO COMMIT - transaction watcher should do it all #

        except Exception as e:
            print(">>>>>>>>>", repr(e))
            self.tearDown(check=False)  # cleanup of connection
            raise
예제 #7
0
def temp_datamanager(game_instance_id, request=None):
    assert game_instance_exists(game_instance_id)
    dm = retrieve_game_instance(game_instance_id, request=request)
    yield dm
    dm.close()
예제 #8
0
def execute():
    for idx, metadata in enumerate(get_all_instances_metadata(), start=1):

        successes = 0
        errors = 0

        instance_id = metadata["instance_id"]

        if metadata["status"] != "active":
            logging.info(
                "Skipping external notifications on obsolete game instance '%s'",
                instance_id)
            continue

        assert metadata["status"] == "active"

        try:

            dm = retrieve_game_instance(instance_id)

            all_notifications = dm.get_characters_external_notifications()
            master_email = dm.get_global_parameter("master_real_email")

            if all_notifications:
                logging.info(
                    "Starting notification of novelties, by emails, for players of game instance '%s'",
                    instance_id)

            for pack in all_notifications:
                username, real_email = pack["username"], pack["real_email"]
                signal_new_radio_messages, signal_new_text_messages = pack[
                    "signal_new_radio_messages"], pack[
                        "signal_new_text_messages"]

                novelties = ""
                if signal_new_radio_messages:
                    novelties += "- la liste de lecture de la webradio a été mise à jour.\n"
                if signal_new_text_messages:
                    novelties += "- vous avez reçu %s nouveaux messages textuels.\n" % signal_new_text_messages

                if not novelties:
                    continue  # no news for the player

                assert novelties
                content_dict = dict(username=username, novelties=novelties)
                message = TEMPLATE % content_dict

                params = dict(subject=SUBJECT,
                              message=message,
                              from_email=settings.SERVER_EMAIL,
                              recipient_list=[real_email] +
                              ([master_email] if master_email else []),
                              fail_silently=False)

                try:
                    logging.info(
                        """Sending novelty notification from '%(from_email)s' to %(recipient_list)r : "%(subject)s"\n%(message)s""",
                        params)
                    send_mail(**params)
                except (SMTPException, EnvironmentError) as e:
                    logging.error(
                        "Couldn't send external notification email to %s",
                        real_email,
                        exc_info=True)
                    errors += 1
                else:
                    logging.info(
                        "Properly sent external notification email to %s",
                        real_email)
                    successes += 1

        except Exception as e:
            logging.critical(
                "Pathological error during external notifications processing on game instance '%s'",
                instance_id,
                exc_info=True)

    return (idx, successes, errors)
def edit_instance_db(request, target_instance_id):
    ## FIXME - add check on game status = maintenance here!!!

    special_message = None
    formatted_data = None
    editing_allowed = True

    try:

        if request.method == "POST" and request.POST.get("db_content"):

            yaml_input = request.POST["db_content"]
            formatted_data = yaml_input  # by default, we redisplay buggy content

            dm = datamanager_administrator.retrieve_game_instance(
                game_instance_id=target_instance_id,
                request=None,
                metadata_checker=datamanager_administrator.
                check_game_is_in_maintenance)

            try:
                data_tree = dm.load_zope_database_from_string_or_tree(
                    yaml_input)  # checks data
            except Exception as e:
                messages.add_message(
                    request, messages.ERROR,
                    _("Data check error (%(exception)r), see details below.") %
                    SDICT(exception=e))
                special_message = traceback.format_exc()
                formatted_data = None  # we force refresh of data
            else:
                datamanager_administrator.replace_existing_game_instance_data(
                    target_instance_id, new_data=data_tree)
                messages.add_message(
                    request, messages.INFO,
                    _("Game instance data was properly replaced."))

        if not formatted_data:  # even if success occurred
            if not special_message:
                special_message = _(
                    "Current DB content is displayed here for editing.")
            dm = datamanager_administrator.retrieve_game_instance(
                game_instance_id=target_instance_id,
                request=None,
                metadata_checker=datamanager_administrator.
                check_game_is_in_maintenance)
            formatted_data = dm.dump_zope_database(width=80)

    except GameMaintenanceError as e:
        # formatted_data might remain as yaml_input
        messages.add_message(request, messages.ERROR, str(e))
        editing_allowed = False
        special_message = _(
            "DB modification is now forbidden, please stash your potential modifications elsewhere and begin the process again."
        )

    return render(
        request,
        "meta_administration/edit_instance_db.html",
        {
            'target_instance_id': target_instance_id,
            'special_message': special_message,
            'editing_allowed':
            editing_allowed,  # FIXME - make it dynamic depending on context - MSG ""
            'formatted_data': formatted_data,
            'notifications': get_messages(request),
        })