def setup_app(): settings = TESTING_SETTINGS.copy() settings['applications'] = ['guillotina.documentation'] aioapp = make_app(settings=settings) @configure.addon( name="myaddon", title="My addon") class MyAddon(Addon): @classmethod def install(cls, site, request): # install code pass @classmethod def uninstall(cls, site, request): # uninstall code pass config = aioapp.config configure.load_configuration( config, 'guillotina.documentation', 'addon') aioapp.config.execute_actions() load_cached_schema()
def guillotina_main(loop): HARD_CACHE.clear() from guillotina import test_package # noqa aioapp = make_app(settings=PG_SETTINGS, loop=loop) aioapp.config.execute_actions() load_cached_schema() yield aioapp
async def test_creator_used_from_content_creation(self, dummy_request): self.request = dummy_request utils.login(self.request) container = await create_content( 'Container', id='guillotina', title='Guillotina') container.__name__ = 'guillotina' utils._p_register(container) import guillotina.tests configure.register_configuration(Folder, dict( type_name="TestType2", behaviors=[], module=guillotina.tests # for registration initialization ), 'contenttype') root = get_utility(IApplication, name='root') configure.load_configuration( root.app.config, 'guillotina.tests', 'contenttype') root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container( container, 'TestType2', 'foobar', creators=('root',), contributors=('root',)) assert obj.creators == ('root',) assert obj.contributors == ('root',) behavior = IDublinCore(obj) assert behavior.creators == ('root',) assert behavior.contributors == ('root',)
def reload_content_configuration(): root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.contrib.dyncontent.contents", "contenttype") root.app.config.execute_actions() load_cached_schema()
def get_server(): global _server if _server is not None: return _server loop = asyncio.get_event_loop() aioapp = make_app( settings={ "applications": ["guillotina.documentation"], "databases": { "db": { "storage": "DUMMY", "dsn": {}, "name": "db" } }, "root_user": { "password": "******" }, "jwt": { "secret": "foobar", "algorithm": "HS256" }, }, loop=loop, ) load_cached_schema() client = loop.run_until_complete(TestClient(aioapp).__aenter__()) _server = {"loop": loop, "client": client, "app": aioapp} return _server
async def test_creator_used_from_content_creation(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) import guillotina.tests configure.register_configuration( Folder, dict( type_name="TestType2", behaviors=[], module=guillotina.tests ), # for registration initialization "contenttype", ) root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.tests", "contenttype") root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container( container, "TestType2", "foobar", creators=("root",), contributors=("root",) ) assert obj.creators == ("root",) assert obj.contributors == ("root",) behavior = IDublinCore(obj) assert behavior.creators == ("root",) assert behavior.contributors == ("root",)
async def test_allowed_types(self, dummy_request): self.request = dummy_request utils.login(self.request) container = await create_content( 'Container', id='guillotina', title='Guillotina') container.__name__ = 'guillotina' utils._p_register(container) import guillotina.tests configure.register_configuration(Folder, dict( type_name="TestType", allowed_types=['Item'], module=guillotina.tests # for registration initialization ), 'contenttype') root = get_utility(IApplication, name='root') configure.load_configuration( root.app.config, 'guillotina.tests', 'contenttype') root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container(container, 'TestType', 'foobar') constrains = IConstrainTypes(obj, None) assert constrains.get_allowed_types() == ['Item'] assert constrains.is_type_allowed('Item') with pytest.raises(NotAllowedContentType): await create_content_in_container(obj, 'TestType', 'foobar') await create_content_in_container(obj, 'Item', 'foobar')
async def test_allowed_types(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) import guillotina.tests configure.register_configuration( Folder, dict( type_name="TestType", allowed_types=["Item"], module=guillotina.tests, # for registration initialization ), "contenttype", ) root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.tests", "contenttype") root.app.config.execute_actions() load_cached_schema() obj = await create_content_in_container(container, "TestType", "foobar") constrains = IConstrainTypes(obj, None) assert constrains.get_allowed_types() == ["Item"] assert constrains.is_type_allowed("Item") with pytest.raises(NotAllowedContentType): await create_content_in_container(obj, "TestType", "foobar") await create_content_in_container(obj, "Item", "foobar")
def dummy_guillotina(loop): from guillotina import test_package # noqa aioapp = make_app(settings=get_dummy_settings(), loop=loop) aioapp.config.execute_actions() load_cached_schema() yield aioapp close_async_tasks()
def guillotina_main(loop): HARD_CACHE.clear() aioapp = make_app(settings=get_pg_settings(), loop=loop) aioapp.config.execute_actions() load_cached_schema() yield aioapp loop.run_until_complete(close_async_tasks(aioapp))
def guillotina_main(loop): HARD_CACHE.clear() from guillotina import test_package # noqa aioapp = make_app(settings=get_pg_settings(), loop=loop) aioapp.config.execute_actions() load_cached_schema() yield aioapp close_async_tasks()
def guillotina_main(loop): globalregistry.reset() aioapp = make_app(settings=get_db_settings(), loop=loop) aioapp.config.execute_actions() load_cached_schema() yield aioapp try: loop.run_until_complete(close_async_tasks(aioapp)) except asyncio.CancelledError: pass
def dummy_guillotina(loop): globalregistry.reset() aioapp = loop.run_until_complete( make_app(settings=get_dummy_settings(), loop=loop)) aioapp.config.execute_actions() load_cached_schema() yield aioapp try: loop.run_until_complete(close_async_tasks(aioapp)) except asyncio.CancelledError: pass
def dummy_guillotina(loop, request): globalregistry.reset() aioapp = loop.run_until_complete( make_app(settings=get_dummy_settings(request.node), loop=loop)) aioapp.config.execute_actions() load_cached_schema() yield aioapp try: loop.run_until_complete(close_async_tasks(aioapp)) except asyncio.CancelledError: pass logout()
def guillotina_in_thread(port): # Create a new loop and set it loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) # Create guillotina app globalregistry.reset() aioapp = loop.run_until_complete( make_app(settings=get_db_settings(), loop=loop)) aioapp.config.execute_actions() load_cached_schema() # Create test server with app server = TestServer(aioapp, loop=loop, port=port) loop.run_until_complete(server.start_server(loop=loop)) loop.run_forever()
async def __aenter__(self): configure.register_configuration(FoobarType, dict( schema=IFoobarType, portal_type="Foobar", behaviors=[] ), 'contenttype') requester = await super(CustomTypeSiteRequesterAsyncContextManager, self).__aenter__() config = requester.root.app.config # now test it... configure.load_configuration( config, 'guillotina.tests', 'contenttype') config.execute_actions() load_cached_schema() return requester
async def test_globally_addable_types(dummy_guillotina): utils.login() async with transaction(db=await get_database("db")): container = await create_content("Container", id="guillotina", title="Guillotina") container.__name__ = "guillotina" utils.register(container) import guillotina.tests # Define BarType which is not globally addable configure.register_configuration( Folder, dict(type_name="BarType", module=guillotina.tests, globally_addable=False), "contenttype") # Define the only content where BarType is addable configure.register_configuration( Folder, dict(type_name="FooType", allowed_types=["BarType"], module=guillotina.tests), "contenttype", ) root = get_utility(IApplication, name="root") configure.load_configuration(root.app.config, "guillotina.tests", "contenttype") root.app.config.execute_actions() load_cached_schema() # Check that BarType can be added in FooType foo = await create_content_in_container(container, "FooType", "foo") await create_content_in_container(foo, "BarType", "bar") # Check that BarType cannot be globally added with pytest.raises(NotAllowedContentType): await create_content_in_container(container, "BarType", "bar") # Check it can be bypassed await create_content_in_container(container, "BarType", "bar", check_constraints=False)
async def __aenter__(self): configure.register_configuration(FoobarType, dict( schema=IFoobarType, type_name="Foobar", behaviors=[ 'guillotina.behaviors.dublincore.IDublinCore' ] ), 'contenttype') requester = await super(CustomTypeContainerRequesterAsyncContextManager, self).__aenter__() config = requester.root.app.config # now test it... configure.load_configuration( config, 'guillotina.tests', 'contenttype') config.execute_actions() load_cached_schema() return requester
async def __aenter__(self): configure.register_configuration( FoobarType, dict( schema=IFoobarType, type_name="Foobar", behaviors=["guillotina.behaviors.dublincore.IDublinCore"], ), "contenttype", ) requester = await super( CustomTypeContainerRequesterAsyncContextManager, self).__aenter__() config = requester.root.app.config # now test it... configure.load_configuration(config, "guillotina.tests", "contenttype") config.execute_actions() load_cached_schema() return requester
def get_server(): global _server if _server is not None: return _server loop = asyncio.new_event_loop() aioapp = loop.run_until_complete( make_app( settings={ "applications": ["guillotina.documentation"], "databases": { "db": { "storage": "DUMMY", "dsn": {}, "name": "db" } }, "root_user": { "password": "******" }, "jwt": { "secret": "foobar", "algorithm": "HS256" }, }, loop=loop, )) aioapp.config.execute_actions() load_cached_schema() server = TestServer(aioapp) loop.run_until_complete(server.start_server(loop=loop)) _server = { "loop": loop, "server": server, "client": TestClient(server, loop=loop), "app": aioapp } return _server
def get_server(): global _server if _server is not None: return _server loop = asyncio.new_event_loop() aioapp = loop.run_until_complete(make_app( settings={ "applications": ["guillotina.documentation"], "databases": { "db": { "storage": "DUMMY", "dsn": {}, "name": "db" } }, "root_user": { "password": "******" }, "jwt": { "secret": "foobar", "algorithm": "HS256" }, }, loop=loop)) aioapp.config.execute_actions() load_cached_schema() server = TestServer(aioapp) loop.run_until_complete(server.start_server(loop=loop)) _server = { 'loop': loop, 'server': server, 'client': TestClient(server, loop=loop), 'app': aioapp } return _server
def make_app(config_file=None, settings=None, loop=None, server_app=None): app_settings.update(_delayed_default_settings) if loop is None: loop = asyncio.get_event_loop() loop.set_task_factory(aiotask_context.task_factory) if config_file is not None: with open(config_file, 'r') as config: settings = json.load(config) elif settings is None: raise Exception('Neither configuration or settings') # Create root Application root = ApplicationRoot(config_file) provide_utility(root, IApplication, 'root') # Initialize global (threadlocal) ZCA configuration config = root.config = ConfigurationMachine() import guillotina import guillotina.db.factory import guillotina.db.writer import guillotina.db.db configure.scan('guillotina.translation') configure.scan('guillotina.renderers') configure.scan('guillotina.api') configure.scan('guillotina.content') configure.scan('guillotina.registry') configure.scan('guillotina.auth') configure.scan('guillotina.json') configure.scan('guillotina.behaviors') configure.scan('guillotina.languages') configure.scan('guillotina.permissions') configure.scan('guillotina.security.security_local') configure.scan('guillotina.security.policy') configure.scan('guillotina.auth.participation') configure.scan('guillotina.catalog.index') configure.scan('guillotina.catalog.catalog') configure.scan('guillotina.framing') configure.scan('guillotina.files') configure.scan('guillotina.annotations') configure.scan('guillotina.constraintypes') configure.scan('guillotina.subscribers') configure.scan('guillotina.db.strategies') configure.scan('guillotina.db.cache') load_application(guillotina, root, settings) config.execute_actions() config.commit() for module_name in settings.get('applications', []): config.begin(module_name) load_application(resolve_dotted_name(module_name), root, settings) config.execute_actions() config.commit() # XXX we clear now to save some memory # it's unclear to me if this is necesary or not but it seems to me that # we don't need things registered in both components AND here. configure.clear() # update *after* plugins loaded update_app_settings(settings) if 'logging' in app_settings: logging.config.dictConfig(app_settings['logging']) # Make and initialize aiohttp app if server_app is None: server_app = make_aiohttp_application() root.app = server_app server_app.root = root server_app.config = config content_type = ContentNegotiatorUtility('content_type', app_settings['renderers'].keys()) language = ContentNegotiatorUtility('language', app_settings['languages'].keys()) provide_utility(content_type, IContentNegotiation, 'content_type') provide_utility(language, IContentNegotiation, 'language') for database in app_settings['databases']: for key, dbconfig in database.items(): factory = get_utility(IDatabaseConfigurationFactory, name=dbconfig['storage']) if asyncio.iscoroutinefunction(factory): future = asyncio.ensure_future(factory(key, dbconfig, server_app), loop=loop) loop.run_until_complete(future) root[key] = future.result() else: root[key] = factory(key, dbconfig) for key, file_path in list_or_dict_items(app_settings['static']): path = resolve_path(file_path).resolve() if not path.exists(): raise Exception('Invalid static directory {}'.format(file_path)) if path.is_dir(): root[key] = StaticDirectory(path) else: root[key] = StaticFile(path) for key, file_path in list_or_dict_items(app_settings['jsapps']): path = resolve_path(file_path).resolve() if not path.exists() or not path.is_dir(): raise Exception('Invalid jsapps directory {}'.format(file_path)) root[key] = JavaScriptApplication(path) root.set_root_user(app_settings['root_user']) if RSA is not None and not app_settings.get('rsa'): key = RSA.generate(2048) pub_jwk = {'k': key.publickey().exportKey('PEM')} priv_jwk = {'k': key.exportKey('PEM')} app_settings['rsa'] = {'pub': pub_jwk, 'priv': priv_jwk} # Set router root server_app.router.set_root(root) for utility in get_all_utilities_registered_for(IAsyncUtility): # In case there is Utilties that are registered if hasattr(utility, 'initialize'): task = asyncio.ensure_future(lazy_apply(utility.initialize, app=server_app), loop=loop) root.add_async_task(utility, task, {}) else: logger.warn(f'No initialize method found on {utility} object') server_app.on_cleanup.append(close_utilities) for util in app_settings['utilities']: root.add_async_utility(util, loop=loop) # Load cached Schemas load_cached_schema() optimize_settings(app_settings) return server_app
async def make_app(config_file=None, settings=None, loop=None, server_app=None): """ Make application from configuration :param config_file: path to configuration file to load :param settings: dictionary of settings :param loop: if not using with default event loop :param settings: provide your own aiohttp application """ # reset app_settings startup_vars = {} for key in app_settings.keys(): if key[0] == "_": startup_vars[key] = app_settings[key] app_settings.clear() app_settings.update(startup_vars) app_settings.update(deepcopy(default_settings)) if loop is None: loop = asyncio.get_event_loop() if config_file is not None: with open(config_file, "r") as config: settings = json.load(config) elif settings is None: raise Exception("Neither configuration or settings") # Create root Application root = ApplicationRoot(config_file, loop) provide_utility(root, IApplication, "root") # Initialize global (threadlocal) ZCA configuration config = root.config = ConfigurationMachine() app_configurator = ApplicationConfigurator( settings.get("applications") or [], config, root, settings) configure.scan("guillotina.renderers") configure.scan("guillotina.api") configure.scan("guillotina.content") configure.scan("guillotina.registry") configure.scan("guillotina.auth") configure.scan("guillotina.json") configure.scan("guillotina.behaviors") configure.scan("guillotina.languages") configure.scan("guillotina.permissions") configure.scan("guillotina.security.security_local") configure.scan("guillotina.security.policy") configure.scan("guillotina.catalog.index") configure.scan("guillotina.catalog.catalog") configure.scan("guillotina.files") configure.scan("guillotina.annotations") configure.scan("guillotina.constraintypes") configure.scan("guillotina.subscribers") configure.scan("guillotina.db.strategies") configure.scan("guillotina.db.storages.vacuum") configure.scan("guillotina.db.cache") configure.scan("guillotina.db.writer") configure.scan("guillotina.db.factory") configure.scan("guillotina.exc_resp") configure.scan("guillotina.fields") configure.scan("guillotina.migrations") # always load guillotina app_configurator.configure_application("guillotina") app_configurator.configure_all_applications() apply_concrete_behaviors() # update *after* plugins loaded update_app_settings(settings) if "logging" in app_settings: try: logging.config.dictConfig(app_settings["logging"]) except Exception: app_logger.error("Could not setup logging configuration", exc_info=True) # Make and initialize aiohttp app if server_app is None: server_app = make_aiohttp_application() root.app = server_app server_app.root = root server_app.config = config for k, v in _moved.items(): # for b/w compatibility, convert these if k in app_settings: app_settings[v] = app_settings[k] del app_settings[k] optimize_settings(app_settings) await notify(ApplicationConfiguredEvent(server_app, loop)) for key, dbconfig in list_or_dict_items(app_settings["databases"]): factory = get_utility(IDatabaseConfigurationFactory, name=dbconfig["storage"]) root[key] = await factory(key, dbconfig, loop) await notify(DatabaseInitializedEvent(root[key])) for key, file_path in list_or_dict_items(app_settings["static"]): path = resolve_path(file_path).resolve() if not path.exists(): raise Exception("Invalid static directory {}".format(file_path)) if path.is_dir(): root[key] = StaticDirectory(path) else: root[key] = StaticFile(path) for key, file_path in list_or_dict_items(app_settings["jsapps"]): path = resolve_path(file_path).resolve() if not path.exists() or not path.is_dir(): raise Exception("Invalid jsapps directory {}".format(file_path)) root[key] = JavaScriptApplication(path) root.set_root_user(app_settings["root_user"]) if app_settings.get("jwk") and app_settings.get("jwk").get( "k") and app_settings.get("jwk").get("kty"): key = jwk.JWK.from_json(json.dumps(app_settings.get("jwk"))) app_settings["jwk"] = key # {"k":"QqzzWH1tYqQO48IDvW7VH7gvJz89Ita7G6APhV-uLMo","kty":"oct"} if not app_settings.get("debug") and app_settings["jwt"].get("secret"): # validate secret secret = app_settings["jwt"]["secret"] if secret == "secret": app_logger.warning( "You are using a very insecure secret key in production mode. " "It is strongly advised that you provide a better value for " "`jwt.secret` in your config.") elif not secure_passphrase(app_settings["jwt"]["secret"]): app_logger.warning( "You are using a insecure secret key in production mode. " "It is recommended that you provide a more complex value for " "`jwt.secret` in your config.") # Set router root server_app.router.set_root(root) server_app.on_cleanup.append(cleanup_app) for key, util in app_settings["load_utilities"].items(): app_logger.info("Adding " + key + " : " + util["provides"]) await notify(BeforeAsyncUtilityLoadedEvent(key, util)) result = root.add_async_utility(key, util, loop=loop) if result is not None: await notify(AfterAsyncUtilityLoadedEvent(key, util, *result)) # Load cached Schemas load_cached_schema() await notify(ApplicationInitializedEvent(server_app, loop)) return server_app
def create_content_factory(proto_name, proto_definition): parent_interface = import_class( proto_definition.get('inherited_interface', 'guillotina.interfaces.content.IFolder')) parent_class = import_class( proto_definition.get('inherited_class', 'guillotina.content.Folder')) schema_fields, tags = get_fields( properties=proto_definition.get('properties')) for fieldset_id, fieldset_list in proto_definition.get('fieldsets', {}).items(): for field_id in fieldset_list: tags.setdefault(field_id, {})['fieldset'] = fieldset_id class_interface = InterfaceClass('I' + proto_name, (parent_interface, ), schema_fields, __module__='guillotina_cms.interfaces') for field_id, tag in tags.items(): for tag_id, tag_metadata in tag.items(): if tag_id in SUPPORTED_DIRECTIVES: if tag_metadata is None: SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id) elif isinstance(tag_metadata, dict): SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, **tag_metadata) elif isinstance(tag_metadata, list): SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, *tag_metadata) elif tag_id == 'fieldset': SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, tag_metadata) elif isinstance(tag_metadata, str): SUPPORTED_DIRECTIVES[tag_id].apply( class_interface, **{field_id: tag_metadata}) klass = type(proto_name, (parent_class, ), {}) klass.__module__ = 'guillotina_cms.dyncontent' setattr(dyncontent, proto_name, klass) behaviors = [] for bhr in proto_definition.get('behaviors', []): if bhr in BEHAVIOR_CACHE: behaviors.append(BEHAVIOR_CACHE[bhr]) else: raise Exception(f"Behavior not found {bhr}") contenttype = { 'schema': class_interface, 'type_name': proto_name, 'allowed_types': proto_definition.get('allowed_types', []), 'add_permission': proto_definition.get('add_permission', 'guillotina.AddContent'), 'behaviors': behaviors } utility = query_utility(IResourceFactory, name=proto_name) if utility is not None: sm = get_global_components() sm.unregisterUtility(utility, IResourceFactory, proto_name) configure.register_configuration(klass, contenttype, 'contenttype') root = get_utility(IApplication, name='root') configure.load_configuration(root.app.config, 'guillotina_cms.dyncontent', 'contenttype') root.app.config.execute_actions() configure.clear() load_cached_schema() # Verify its created if proto_name in FACTORY_CACHE: del FACTORY_CACHE[proto_name] get_cached_factory(proto_name)
async def make_app(config_file=None, settings=None, loop=None, server_app=None): ''' Make application from configuration :param config_file: path to configuration file to load :param settings: dictionary of settings :param loop: if not using with default event loop :param settings: provide your own aiohttp application ''' # reset app_settings startup_vars = {} for key in app_settings.keys(): if key[0] == '_': startup_vars[key] = app_settings[key] app_settings.clear() app_settings.update(startup_vars) app_settings.update(default_settings) if loop is None: loop = asyncio.get_event_loop() # chainmap task factory is actually very important # default task factory uses inheritance in a way # that bubbles back down. So it's possible for a sub-task # to clear out the request of the parent task loop.set_task_factory(aiotask_context.chainmap_task_factory) if config_file is not None: with open(config_file, 'r') as config: settings = json.load(config) elif settings is None: raise Exception('Neither configuration or settings') # Create root Application root = ApplicationRoot(config_file, loop) provide_utility(root, IApplication, 'root') # Initialize global (threadlocal) ZCA configuration config = root.config = ConfigurationMachine() import guillotina import guillotina.db.factory import guillotina.db.writer import guillotina.db.db configure.scan('guillotina.renderers') configure.scan('guillotina.api') configure.scan('guillotina.content') configure.scan('guillotina.registry') configure.scan('guillotina.auth') configure.scan('guillotina.json') configure.scan('guillotina.behaviors') configure.scan('guillotina.languages') configure.scan('guillotina.permissions') configure.scan('guillotina.security.security_local') configure.scan('guillotina.security.policy') configure.scan('guillotina.auth.participation') configure.scan('guillotina.catalog.index') configure.scan('guillotina.catalog.catalog') configure.scan('guillotina.files') configure.scan('guillotina.annotations') configure.scan('guillotina.constraintypes') configure.scan('guillotina.subscribers') configure.scan('guillotina.db.strategies') configure.scan('guillotina.db.cache') configure.scan('guillotina.exc_resp') configure.scan('guillotina.fields') configure.scan('guillotina.migrations') load_application(guillotina, root, settings) config.execute_actions() config.commit() configured = ['guillotina'] for module_name in settings.get('applications') or []: configure_application(module_name, config, root, settings, configured) apply_concrete_behaviors() # update *after* plugins loaded update_app_settings(settings) if 'logging' in app_settings: logging.config.dictConfig(app_settings['logging']) # Make and initialize aiohttp app if server_app is None: server_app = make_aiohttp_application() root.app = server_app server_app.root = root server_app.config = config optimize_settings(app_settings) await notify(ApplicationConfiguredEvent(server_app, loop)) for key, dbconfig in list_or_dict_items(app_settings['databases']): factory = get_utility(IDatabaseConfigurationFactory, name=dbconfig['storage']) root[key] = await factory(key, dbconfig, loop) await notify(DatabaseInitializedEvent(root[key])) for key, file_path in list_or_dict_items(app_settings['static']): path = resolve_path(file_path).resolve() if not path.exists(): raise Exception('Invalid static directory {}'.format(file_path)) if path.is_dir(): root[key] = StaticDirectory(path) else: root[key] = StaticFile(path) for key, file_path in list_or_dict_items(app_settings['jsapps']): path = resolve_path(file_path).resolve() if not path.exists() or not path.is_dir(): raise Exception('Invalid jsapps directory {}'.format(file_path)) root[key] = JavaScriptApplication(path) root.set_root_user(app_settings['root_user']) if app_settings.get('jwk') and\ app_settings.get('jwk').get('k') and\ app_settings.get('jwk').get('kty'): key = jwk.JWK.from_json(json.dumps(app_settings.get('jwk'))) app_settings['jwk'] = key # {"k":"QqzzWH1tYqQO48IDvW7VH7gvJz89Ita7G6APhV-uLMo","kty":"oct"} if not app_settings.get('debug') and app_settings['jwt'].get('secret'): # validate secret secret = app_settings['jwt']['secret'] if secret == 'secret': logger.warning( 'You are using a very insecure secret key in production mode. ' 'It is strongly advised that you provide a better value for ' '`jwt.secret` in your config.') elif not secure_passphrase(app_settings['jwt']['secret']): logger.warning( 'You are using a insecure secret key in production mode. ' 'It is recommended that you provide a more complex value for ' '`jwt.secret` in your config.') # Set router root server_app.router.set_root(root) server_app.on_cleanup.append(cleanup_app) for util in app_settings.get('utilities') or []: logger.warn('Adding : ' + util['provides']) root.add_async_utility(util['provides'], util, loop=loop) for key, util in app_settings['load_utilities'].items(): logger.info('Adding ' + key + ' : ' + util['provides']) root.add_async_utility(key, util, loop=loop) # Load cached Schemas load_cached_schema() await notify(ApplicationInitializedEvent(server_app, loop)) return server_app
async def make_app(config_file=None, settings=None, loop=None, server_app=None): # reset app_settings app_settings.clear() app_settings.update(default_settings) if loop is None: loop = asyncio.get_event_loop() # chainmap task factory is actually very important # default task factory uses inheritance in a way # that bubbles back down. So it's possible for a sub-task # to clear out the request of the parent task loop.set_task_factory(aiotask_context.chainmap_task_factory) if config_file is not None: with open(config_file, 'r') as config: settings = json.load(config) elif settings is None: raise Exception('Neither configuration or settings') # Create root Application root = ApplicationRoot(config_file, loop) provide_utility(root, IApplication, 'root') # Initialize global (threadlocal) ZCA configuration config = root.config = ConfigurationMachine() import guillotina import guillotina.db.factory import guillotina.db.writer import guillotina.db.db configure.scan('guillotina.renderers') configure.scan('guillotina.api') configure.scan('guillotina.content') configure.scan('guillotina.registry') configure.scan('guillotina.auth') configure.scan('guillotina.json') configure.scan('guillotina.behaviors') configure.scan('guillotina.languages') configure.scan('guillotina.permissions') configure.scan('guillotina.security.security_local') configure.scan('guillotina.security.policy') configure.scan('guillotina.auth.participation') configure.scan('guillotina.catalog.index') configure.scan('guillotina.catalog.catalog') configure.scan('guillotina.files') configure.scan('guillotina.annotations') configure.scan('guillotina.constraintypes') configure.scan('guillotina.subscribers') configure.scan('guillotina.db.strategies') configure.scan('guillotina.db.cache') configure.scan('guillotina.exc_resp') configure.scan('guillotina.fields') load_application(guillotina, root, settings) config.execute_actions() config.commit() configured = ['guillotina'] for module_name in settings.get('applications') or []: configure_application(module_name, config, root, settings, configured) apply_concrete_behaviors() # update *after* plugins loaded update_app_settings(settings) if 'logging' in app_settings: logging.config.dictConfig(app_settings['logging']) # Make and initialize aiohttp app if server_app is None: server_app = make_aiohttp_application() root.app = server_app server_app.root = root server_app.config = config optimize_settings(app_settings) await notify(ApplicationConfiguredEvent(server_app, loop)) for key, dbconfig in list_or_dict_items(app_settings['databases']): factory = get_utility(IDatabaseConfigurationFactory, name=dbconfig['storage']) root[key] = await factory(key, dbconfig, loop) await notify(DatabaseInitializedEvent(root[key])) for key, file_path in list_or_dict_items(app_settings['static']): path = resolve_path(file_path).resolve() if not path.exists(): raise Exception('Invalid static directory {}'.format(file_path)) if path.is_dir(): root[key] = StaticDirectory(path) else: root[key] = StaticFile(path) for key, file_path in list_or_dict_items(app_settings['jsapps']): path = resolve_path(file_path).resolve() if not path.exists() or not path.is_dir(): raise Exception('Invalid jsapps directory {}'.format(file_path)) root[key] = JavaScriptApplication(path) root.set_root_user(app_settings['root_user']) if RSA is not None and not app_settings.get('rsa'): key = RSA.generate(2048) pub_jwk = {'k': key.publickey().exportKey('PEM')} priv_jwk = {'k': key.exportKey('PEM')} app_settings['rsa'] = {'pub': pub_jwk, 'priv': priv_jwk} # Set router root server_app.router.set_root(root) server_app.on_cleanup.append(cleanup_app) for util in app_settings.get('utilities') or []: logger.warn('Adding : ' + util['provides']) root.add_async_utility(util['provides'], util, loop=loop) for key, util in app_settings['load_utilities'].items(): logger.info('Adding ' + key + ' : ' + util['provides']) root.add_async_utility(key, util, loop=loop) # Load cached Schemas load_cached_schema() await notify(ApplicationInitializedEvent(server_app, loop)) return server_app
def create_behaviors_factory(proto_name, proto_definition): if proto_definition.get('for', None) is None: raise Exception('We need a for interface') else: for_ = import_class(proto_definition.get('for')) if for_ is None: raise Exception('Wrong for interface') parent_class = import_class( proto_definition.get( 'inherited_class', 'guillotina.behaviors.instance.AnnotationBehavior')) schema_fields, tags = get_fields( properties=proto_definition.get('properties')) base_interface = proto_definition.get('base_interface', None) if base_interface is None: base_interface = Interface class_interface = InterfaceClass('I' + proto_name, (base_interface, ), schema_fields, __module__='guillotina_cms.interfaces') for field_id, tag in tags.items(): for tag_id, tag_metadata in tag.items(): if tag_id in SUPPORTED_DIRECTIVES: SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id, tag_metadata) klass = type(proto_name, (parent_class, ), {}) klass.__module__ = 'guillotina_cms.behaviors' behavior = { 'for_': for_, 'provides': class_interface, 'data_key': proto_definition.get('data_key', 'default'), 'auto_serialize': proto_definition.get('auto_serialize', True), 'name': proto_name, 'name_only': proto_definition.get('name_only', False), 'title': proto_definition.get('title', ''), 'marker': proto_definition.get('marker', None), 'description': proto_definition.get('description', '') } configure.register_configuration(klass, behavior, 'behavior') root = get_utility(IApplication, name='root') configure.load_configuration(root.app.config, 'guillotina_cms.behaviors', 'behavior') root.app.config.execute_actions() configure.clear() load_cached_schema() # Verify its created interface_name = 'guillotina_cms.interfaces.I' + proto_name utility = get_utility(IBehavior, name=interface_name) interface_name = 'guillotina_cms.interfaces.I' + proto_name utility2 = get_utility(IBehavior, name=proto_name) assert BEHAVIOR_CACHE[interface_name] == class_interface utility.interface == class_interface utility2.interface == class_interface
def dummy_guillotina(loop): aioapp = make_app(settings=get_dummy_settings(), loop=loop) aioapp.config.execute_actions() load_cached_schema() yield aioapp loop.run_until_complete(close_async_tasks(aioapp))
async def run(self, arguments, settings, app): load_cached_schema() process_command_file(arguments.input, arguments.endpoint, arguments.output)
def dummy_guillotina(loop): from guillotina import test_package # noqa aioapp = make_app(settings=DUMMY_SETTINGS, loop=loop) aioapp.config.execute_actions() load_cached_schema() return aioapp
async def make_app(config_file=None, settings=None, loop=None, server_app=None): ''' Make application from configuration :param config_file: path to configuration file to load :param settings: dictionary of settings :param loop: if not using with default event loop :param settings: provide your own aiohttp application ''' # reset app_settings startup_vars = {} for key in app_settings.keys(): if key[0] == '_': startup_vars[key] = app_settings[key] app_settings.clear() app_settings.update(startup_vars) app_settings.update(deepcopy(default_settings)) if loop is None: loop = asyncio.get_event_loop() # chainmap task factory is actually very important # default task factory uses inheritance in a way # that bubbles back down. So it's possible for a sub-task # to clear out the request of the parent task loop.set_task_factory(aiotask_context.chainmap_task_factory) if config_file is not None: with open(config_file, 'r') as config: settings = json.load(config) elif settings is None: raise Exception('Neither configuration or settings') # Create root Application root = ApplicationRoot(config_file, loop) provide_utility(root, IApplication, 'root') # Initialize global (threadlocal) ZCA configuration config = root.config = ConfigurationMachine() app_configurator = ApplicationConfigurator( settings.get('applications') or [], config, root, settings ) configure.scan('guillotina.renderers') configure.scan('guillotina.api') configure.scan('guillotina.content') configure.scan('guillotina.registry') configure.scan('guillotina.auth') configure.scan('guillotina.json') configure.scan('guillotina.behaviors') configure.scan('guillotina.languages') configure.scan('guillotina.permissions') configure.scan('guillotina.security.security_local') configure.scan('guillotina.security.policy') configure.scan('guillotina.auth.participation') configure.scan('guillotina.catalog.index') configure.scan('guillotina.catalog.catalog') configure.scan('guillotina.files') configure.scan('guillotina.annotations') configure.scan('guillotina.constraintypes') configure.scan('guillotina.subscribers') configure.scan('guillotina.db.strategies') configure.scan('guillotina.db.cache') configure.scan('guillotina.db.writer') configure.scan('guillotina.db.factory') configure.scan('guillotina.exc_resp') configure.scan('guillotina.fields') configure.scan('guillotina.migrations') # always load guillotina app_configurator.configure_application('guillotina') app_configurator.configure_all_applications() apply_concrete_behaviors() # update *after* plugins loaded update_app_settings(settings) if 'logging' in app_settings: try: logging.config.dictConfig(app_settings['logging']) except Exception: logger.error('Could not setup logging configuration', exc_info=True) # Make and initialize aiohttp app if server_app is None: server_app = make_aiohttp_application() root.app = server_app server_app.root = root server_app.config = config optimize_settings(app_settings) await notify(ApplicationConfiguredEvent(server_app, loop)) for key, dbconfig in list_or_dict_items(app_settings['databases']): factory = get_utility( IDatabaseConfigurationFactory, name=dbconfig['storage']) root[key] = await factory(key, dbconfig, loop) await notify(DatabaseInitializedEvent(root[key])) for key, file_path in list_or_dict_items(app_settings['static']): path = resolve_path(file_path).resolve() if not path.exists(): raise Exception('Invalid static directory {}'.format(file_path)) if path.is_dir(): root[key] = StaticDirectory(path) else: root[key] = StaticFile(path) for key, file_path in list_or_dict_items(app_settings['jsapps']): path = resolve_path(file_path).resolve() if not path.exists() or not path.is_dir(): raise Exception('Invalid jsapps directory {}'.format(file_path)) root[key] = JavaScriptApplication(path) root.set_root_user(app_settings['root_user']) if app_settings.get('jwk') and\ app_settings.get('jwk').get('k') and\ app_settings.get('jwk').get('kty'): key = jwk.JWK.from_json(json.dumps(app_settings.get('jwk'))) app_settings['jwk'] = key # {"k":"QqzzWH1tYqQO48IDvW7VH7gvJz89Ita7G6APhV-uLMo","kty":"oct"} if not app_settings.get('debug') and app_settings['jwt'].get('secret'): # validate secret secret = app_settings['jwt']['secret'] if secret == 'secret': logger.warning( 'You are using a very insecure secret key in production mode. ' 'It is strongly advised that you provide a better value for ' '`jwt.secret` in your config.') elif not secure_passphrase(app_settings['jwt']['secret']): logger.warning( 'You are using a insecure secret key in production mode. ' 'It is recommended that you provide a more complex value for ' '`jwt.secret` in your config.') # Set router root server_app.router.set_root(root) server_app.on_cleanup.append(cleanup_app) for util in app_settings.get('utilities') or []: logger.warn('Adding : ' + util['provides']) root.add_async_utility(util['provides'], util, loop=loop) for key, util in app_settings['load_utilities'].items(): logger.info('Adding ' + key + ' : ' + util['provides']) root.add_async_utility(key, util, loop=loop) # Load cached Schemas load_cached_schema() await notify(ApplicationInitializedEvent(server_app, loop)) return server_app
async def app_initialized(event): factory = get_utility(IResourceFactory, "Container") # factory = get_cached_factory("Container") factory.behaviors = (IDublinCore, ICMSBehavior, IBlocks) load_cached_schema()