def update(self): data = [] fields = config.get_cfg_storage(FIELD_ID) previews = config.get_cfg_storage(PREVIEW_ID) for name, cls in fields.items(): data.append({'name': name, 'doc': cls.__doc__, 'preview': previews.get(cls)}) data.sort() self.fields = data
def run(self): # print defaults if self.options.printcfg: data = config.get_cfg_storage(SETTINGS_OB_ID).export(True) parser = configparser.ConfigParser(dict_type=OrderedDict) for key, val in sorted(data.items()): parser.set(configparser.DEFAULTSECT, key, val.replace('%', '%%')) fp = NativeIO() try: parser.write(fp) finally: pass print (fp.getvalue()) return if self.options.all: section = '' else: section = self.options.section # print description groups = sorted(config.get_cfg_storage(ID_SETTINGS_GROUP).items(), key = lambda item: item[1].__title__) for name, group in groups: if section and name != section: continue print ('') title = group.__title__ or name print (grpTitleWrap.fill('{0} ({1})'.format(title, name))) if group.__description__: print (grpDescriptionWrap.fill( group.__description__)) print ('') for node in group.__fields__.values(): default = '<required>' if node.required else node.default print (nameWrap.fill( ('%s.%s: %s (%s: %s)' % ( name, node.name, node.title, node.__class__.__name__, default)))) print (nameTitleWrap.fill(node.description)) print ('')
def run(self): # print defaults if self.options.printcfg: data = config.get_cfg_storage(SETTINGS_OB_ID).export(True) parser = configparser.ConfigParser(dict_type=OrderedDict) for key, val in sorted(data.items()): parser.set(configparser.DEFAULTSECT, key, val.replace('%', '%%')) fp = NativeIO() try: parser.write(fp) finally: pass print (fp.getvalue()) return if self.options.all: section = '' else: section = self.options.section # print description groups = sorted(config.get_cfg_storage(ID_SETTINGS_GROUP).items()) for name, group in groups: if section and name != section: continue print ('') title = group.__title__ or name print (grpTitleWrap.fill(title)) if group.__description__: print (grpDescriptionWrap.fill( group.__description__)) print ('') for node in group.__fields__.values(): default = '<required>' if node.required else node.default print (nameWrap.fill( ('%s.%s: %s (%s: %s)' % ( name, node.name, node.title, node.__class__.__name__, default)))) print (nameTitleWrap.fill(node.description)) print ('')
def test_floatPreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.FloatField], fieldpreviews.floatPreview) request = DummyRequest() html = fieldpreviews.floatPreview(request) self.assertIn('Float field', html)
def test_intPreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.IntegerField], fieldpreviews.intPreview) request = DummyRequest() html = fieldpreviews.intPreview(request) self.assertIn('Integer field', html)
def test_linesPreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.LinesField], fieldpreviews.linesPreview) request = DummyRequest() html = fieldpreviews.linesPreview(request) self.assertIn('Lines field', html)
def test_radioPreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.RadioField], fieldpreviews.radioPreview) request = DummyRequest() html = fieldpreviews.radioPreview(request) self.assertIn('Radio field', html)
def test_boolPreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.BoolField], fieldpreviews.boolPreview) request = DummyRequest() html = fieldpreviews.boolPreview(request) self.assertIn('Boolean field', html)
def test_rest_registerService_apidoc(self): from ptahcms import restsrv restsrv.RestService('test', 'Test service') self.init_ptah() srv = config.get_cfg_storage(restsrv.ID_REST)['test'] @srv.action('action', 'Action') def raction(request, *args): """ doc string """ self.assertIn('apidoc', srv.actions) info = srv(self.make_request(), 'apidoc') self.assertEqual(info['name'], 'test') self.assertEqual(info['title'], 'Test service') self.assertEqual(len(info['actions']), 2) self.assertEqual(info['actions'][0]['name'], 'apidoc') self.assertEqual( info['actions'][0]['__link__'], 'http://example.com/apidoc') self.assertEqual(info['actions'][1]['name'], 'action') self.assertEqual( info['actions'][1]['__link__'], 'http://example.com/action')
def auth_checker(checker, __cfg=None, __depth=1): """Register authentication checker. Checker function accepts :py:class:`ptah.authentication.AuthInfo` object. :param checker: Checker function. Checker function interface :py:func:`ptah.interfaces.auth_checker` .. code-block:: python @ptah.auth_checker def my_checker(info): ... """ info = config.DirectiveInfo(__depth) discr = (AUTH_CHECKER_ID, hash(checker)) intr = config.Introspectable( AUTH_CHECKER_ID, discr, checker.__name__, AUTH_CHECKER_ID) intr['name'] = '{0}.{1}'.format(info.codeinfo.module, checker.__name__) intr['callable'] = checker intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, checker: config.get_cfg_storage(AUTH_CHECKER_ID)\ .update({id(checker): checker}), (checker,), discriminator=discr, introspectables=(intr,)), __cfg) return checker
def get_principal_bylogin(self, login): providers = config.get_cfg_storage(AUTH_PROVIDER_ID) for pname, provider in providers.items(): principal = provider.get_principal_bylogin(login) if principal is not None: return principal
def update(self): ev = self.request.params.get('ev') all_events = config.get_cfg_storage(directives.EVENT_ID) self.event = event = all_events.get(ev) if event is None: events = [] for n, ev in all_events.items(): if isinstance(n, basestring): events.append((ev.title, ev)) events.sort() self.events = [ev for _t, ev in events] else: pkgs = list_packages() evinst = event.instance seen = set() actions = [] for pkg in pkgs: for action in directives.scan(pkg, seen, exclude): if action.discriminator[0] == 'ptah.config:subscriber': required = action.args[2] if len(required) == 2 and required[1] == evinst: actions.append(action) elif required[0] == evinst: actions.append(action) self.actions = actions
def authenticate(self, credentials): providers = config.get_cfg_storage(AUTH_PROVIDER_ID) for pname, provider in providers.items(): principal = provider.authenticate(credentials) if principal is not None: info = AuthInfo(principal) for checker in \ config.get_cfg_storage(AUTH_CHECKER_ID).values(): if not checker(info): return info info.status = True return info return AuthInfo(None)
def pyramid_auth_provider(config, name, provider): """ pyramid configurator directive for authentication provider registration:: class AuthProvider(object): ... config = Configurator() config.include('ptah') config.ptah_auth_provider('my-provider', AuthProvider()) """ info = ptah.config.DirectiveInfo() discr = (AUTH_PROVIDER_ID, name) intr = ptah.config.Introspectable( AUTH_PROVIDER_ID, discr, name, AUTH_PROVIDER_ID) intr['id'] = name intr['name'] = '{0}.{1}'.format( info.codeinfo.module, provider.__class__.__name__) intr['provider'] = provider intr['codeinfo'] = info.codeinfo config.action( discr, lambda config, n, p: \ config.get_cfg_storage(AUTH_PROVIDER_ID).update({n: p}), (config, name, provider), introspectables=(intr,))
def getInfo(self, action): factory, ifaces = action.args[1:] factoryInfo = '%s.%s'%(action.info.module.__name__, factory.__name__) if len(action.args[2]) > 1: obj = action.args[2][0] klass = action.args[2][-1] event = config.get_cfg_storage(directives.EVENT_ID).get( action.args[2][-1], None) else: obj = None klass = action.args[2][0] event = config.get_cfg_storage(directives.EVENT_ID).get( action.args[2][0], None) return locals()
def test_choicePreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.ChoiceField], fieldpreviews.choicePreview) request = DummyRequest() html = fieldpreviews.choicePreview(request) self.assertIn('Choice field', html)
def __iter__(self): acls = config.get_cfg_storage(ID_ACL) for aname in self.acls: acl = acls.get(aname) if acl is not None: for rec in acl: yield rec
def register_type_impl(config, cls, tinfo, name, fieldset=None, fieldNames=None, **kw): # generate schema fieldset = kw.get('fieldset') if fieldset is None: kw['fieldset'] = ptah.generate_fieldset(cls, fieldNames=fieldNames, namesFilter=names_filter) log.info("Generating fieldset for %s content type.", cls) if 'global_allow' not in kw and not issubclass(cls, Content): kw['global_allow'] = False tinfo.__dict__.update(kw) tinfo.cls = cls config.get_cfg_storage(TYPES_DIR_ID)[tinfo.__uri__] = tinfo # sql query for content resolver cls.__uri_sql_get__ = ptah.QueryFreezer( lambda: ptah.get_session().query(cls) \ .filter(cls.__uri__ == sqla.sql.bindparam('uri'))) # build cms actions build_class_actions(cls)
def list_types(self, container): if container.__type__ is not self or \ not isinstance(container, BaseContainer): return () types = [] all_types = config.get_cfg_storage(TYPES_DIR_ID) if self.filter_content_types: allowed_types = self.allowed_content_types if callable(allowed_types): allowed_types = allowed_types(container) for tinfo in allowed_types: if isinstance(tinfo, string_types): tinfo = all_types.get('cms-type:%s'%tinfo) if tinfo and tinfo.is_allowed(container): types.append(tinfo) else: for tinfo in all_types.values(): if tinfo.global_allow and tinfo.is_allowed(container): types.append(tinfo) return types
def __init__(self, name, title, description='', prefix='role:', system=False): id = '%s%s' % (prefix, name) self.id = id self.name = name self.title = title self.description = description self.system = system self.allowed = set() self.denied = set() # conflict detection and introspection info = config.DirectiveInfo() discr = (ID_ROLE, name) intr = config.Introspectable(ID_ROLE, discr, title, ID_ROLE) intr['role'] = self intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, r: \ config.get_cfg_storage(ID_ROLE).update({r.name: r}), (self, ), discriminator=discr, introspectables=(intr,)) )
def test_rest_api_auth(self): from ptah.rest import Api, Login from ptah import authentication self.init_ptah() config.get_cfg_storage( authentication.AUTH_PROVIDER_ID)['test'] = Provider() request = DummyRequest(params={'login': '******', 'password': '******'}) login = Login(request) info = json.loads(login().text) request = DummyRequest(environ={'HTTP_X_AUTH_TOKEN': 'unknown'}) request.matchdict = {'service': 'cms', 'subpath': ()} result = Api(request) self.assertEqual(ptah.auth_service.get_userid(), None) token = info['auth-token'] request = DummyRequest(environ={'HTTP_X_AUTH_TOKEN': token}) request.matchdict = {'service': 'cms', 'subpath': ()} result = Api(request) self.assertEqual(ptah.auth_service.get_userid(), 'testprincipal:1')
def register_type_impl( config, cls, tinfo, name, fieldset=None, fieldNames=None, **kw): # generate schema fieldset = kw.get('fieldset') if fieldset is None: kw['fieldset'] = ptah.generate_fieldset( cls, fieldNames=fieldNames, namesFilter=names_filter) log.info("Generating fieldset for %s content type.", cls) if 'global_allow' not in kw and not issubclass(cls, Content): kw['global_allow'] = False tinfo.__dict__.update(kw) tinfo.cls = cls config.get_cfg_storage(TYPES_DIR_ID)[tinfo.__uri__] = tinfo # sql query for content resolver cls.__uri_sql_get__ = ptah.QueryFreezer( lambda: ptah.get_session().query(cls) \ .filter(cls.__uri__ == sqla.sql.bindparam('uri'))) # build cms actions build_class_actions(cls)
def test_rest_registerService_apidoc(self): import ptah.rest ptah.rest.RestService('test', 'Test service') self.init_ptah() srv = config.get_cfg_storage(ptah.rest.ID_REST)['test'] @srv.action('action', 'Action') def raction(request, *args): """ doc string """ self.assertIn('apidoc', srv.actions) info = srv(self.make_request(), 'apidoc') self.assertEqual(info['name'], 'test') self.assertEqual(info['title'], 'Test service') self.assertEqual(len(info['actions']), 2) self.assertEqual(info['actions'][0]['name'], 'apidoc') self.assertEqual(info['actions'][0]['__link__'], 'http://example.com/apidoc') self.assertEqual(info['actions'][1]['name'], 'action') self.assertEqual(info['actions'][1]['__link__'], 'http://example.com/action')
def auth_checker(checker, __cfg=None, __depth=1): """Register authentication checker. Checker function accepts :py:class:`ptah.authentication.AuthInfo` object. :param checker: Checker function. Checker function interface :py:func:`ptah.interfaces.auth_checker` .. code-block:: python @ptah.auth_checker def my_checker(info): ... """ info = config.DirectiveInfo(__depth) discr = (AUTH_CHECKER_ID, hash(checker)) intr = config.Introspectable(AUTH_CHECKER_ID, discr, checker.__name__, 'ptah-authchecker') intr['name'] = '{0}.{1}'.format(info.codeinfo.module, checker.__name__) intr['callable'] = checker intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, checker: config.get_cfg_storage(AUTH_CHECKER_ID)\ .update({id(checker): checker}), (checker,), discriminator=discr, introspectables=(intr,)), __cfg) return checker
def register_settings(name, *fields, **kw): """ register settings group """ iname = name for ch in ('.', '-'): iname = iname.replace(ch, '_') category = InterfaceClass('SettingsGroup:%s' % iname.upper(), (), __doc__='Settings group: %s' % name, __module__='ptah.config.settings') for field in fields: field.required = False if field.default is form.null: raise StopException( 'Default value is required for "{0}.{1}"'.format( name, field.name)) group = Group(name=name, *fields, **kw) interface.directlyProvides(Group, category) info = config.DirectiveInfo() discr = (ID_SETTINGS_GROUP, name) intr = config.Introspectable(ID_SETTINGS_GROUP, discr, group.__title__, ID_SETTINGS_GROUP) intr['name'] = name intr['group'] = group intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, group: config.get_cfg_storage(ID_SETTINGS_GROUP)\ .update({group.__name__: group.clone(config.registry)}), (group,), discriminator=discr, introspectables=(intr,)) )
def __init__(self, name, title, description='', prefix='role:', system=False): id = '%s%s' % (prefix, name) self.id = id self.name = name self.title = title self.description = description self.system = system self.allowed = set() self.denied = set() # conflict detection and introspection info = config.DirectiveInfo() discr = (ID_ROLE, name) intr = config.Introspectable(ID_ROLE, discr, title, 'ptah-role') intr['role'] = self intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, r: \ config.get_cfg_storage(ID_ROLE).update({r.name: r}), (self, ), discriminator=discr, introspectables=(intr,)) )
def test_rest_registerService_apidoc(self): import ptah.rest ptah.rest.RestService('test', 'Test service') self._init_ptah() srv = config.get_cfg_storage(ptah.rest.REST_ID)['test'] @srv.action('action', 'Action') def raction(request, *args): """ doc string """ self.assertIn('apidoc', srv.actions) info = srv(self._makeRequest(), 'apidoc') self.assertEqual(info['name'], 'test') self.assertEqual(info['title'], 'Test service') self.assertEqual(len(info['actions']), 2) self.assertEqual(info['actions'][0]['name'], 'apidoc') self.assertEqual( info['actions'][0]['__link__'], 'http://localhost:8080/apidoc') self.assertEqual(info['actions'][1]['name'], 'action') self.assertEqual( info['actions'][1]['__link__'], 'http://localhost:8080/action')
def render_includes(request): """ Renders HTML for all included libraries for this request. :param request: Pyramid request """ _libraries = config.get_cfg_storage(LIBRARY_ID) seen = set() libraries = [] libs = getattr(request, '__includes', None) if libs is None: return '' def _process(l_id): lib = _libraries.get(l_id) if lib is None: seen.add(l_id) return for require in lib.require: if require not in seen: _process(require) seen.add(l_id) libraries.append(lib) for id in libs: if id not in seen: _process(id) return '\n'.join(lib.render(request) for lib in libraries)
def test_rest_api_auth(self): from ptah.rest import Api, Login from ptah import authentication self._init_ptah() config.get_cfg_storage( authentication.AUTH_PROVIDER_ID)['test'] = Provider() request = DummyRequest(params = {'login': '******', 'password': '******'}) login = Login(request) info = simplejson.loads(login.render()) request = DummyRequest(environ = {'HTTP_X_AUTH_TOKEN': 'unknown'}) request.matchdict = {'service': 'cms', 'subpath': ()} api = Api(request) api.render() self.assertEqual(ptah.authService.get_userid(), None) token = info['auth-token'] request = DummyRequest(environ = {'HTTP_X_AUTH_TOKEN': token}) request.matchdict = {'service': 'cms', 'subpath': ()} api = Api(request) api.render() self.assertEqual(ptah.authService.get_userid(), 'testprincipal:1')
def render_includes(request): _libraries = config.get_cfg_storage(LIBRARY_ID) seen = set() libraries = [] libs = getattr(request, '__includes', None) if libs is None: return u'' def _process(l_id): lib = _libraries.get(l_id) if lib is None: seen.add(l_id) return for require in lib.require: if require not in seen: _process(require) seen.add(l_id) libraries.append(lib) for id in libs: if id not in seen: _process(id) return u'\n'.join(lib.render(request) for lib in libraries)
def get_types(): """ Get all registered types. :Returns: - mapping of all registered identifier and TypeInformation """ return config.get_cfg_storage(TYPES_DIR_ID)
def register_settings(name, *fields, **kw): """ register settings group """ iname = name for ch in ('.', '-'): iname = iname.replace(ch, '_') category = InterfaceClass( 'SettingsGroup:%s' % iname.upper(), (), __doc__='Settings group: %s' % name, __module__='ptah.config.settings') for field in fields: field.required = False if field.default is form.null: raise StopException( 'Default value is required for "{0}.{1}"'.format(name,field.name)) group = Group(name=name, *fields, **kw) interface.directlyProvides(Group, category) info = config.DirectiveInfo() discr = (ID_SETTINGS_GROUP, name) intr = config.Introspectable( ID_SETTINGS_GROUP, discr, group.__title__, ID_SETTINGS_GROUP) intr['name'] = name intr['group'] = group intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, group: config.get_cfg_storage(ID_SETTINGS_GROUP)\ .update({group.__name__: group.clone(config.registry)}), (group,), discriminator=discr, introspectables=(intr,)) )
def __iter__(self): acls = config.get_cfg_storage(ACL_ID) for aname in self.acls: acl = acls.get(aname) if acl is not None: for rec in acl: yield rec
def __getitem__(self, key): if key not in CONFIG.disable_modules: mod = config.get_cfg_storage(MANAGE_ID).get(key) if mod is not None: return mod(self, self.request) raise KeyError(key)
def load_dbsettings(registry=None): session = ptah.get_session() if not (session.bind and SettingRecord.__table__.exists()): return # load db settings s_ob = config.get_cfg_storage(SETTINGS_OB_ID, registry, default_factory=Settings) s_ob.load_fromdb()
def test_decimalPreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.DecimalField], fieldpreviews.decimalPreview) request = DummyRequest() html = fieldpreviews.decimalPreview(request) self.assertIn('Decimal field', html)
def test_textareaPreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.TextAreaField], fieldpreviews.textareaPreview) request = DummyRequest() html = fieldpreviews.textareaPreview(request) self.assertIn('TextArea field', html)
def get_principal_byemail(self, email): """ Return principal by email """ providers = config.get_cfg_storage(AUTH_PROVIDER_ID) for pname, provider in providers.items(): principal = provider.get_principal_byemail(email) if principal is not None: return principal
def test_passwordPreview(self): previews = config.get_cfg_storage(PREVIEW_ID) self.assertIs(previews[form.PasswordField], fieldpreviews.passwordPreview) request = DummyRequest() html = fieldpreviews.passwordPreview(request) self.assertIn('Password field', html)
def pyramid_get_settings(config, grp): """ pyramid configurator directive for getting settings group:: config = Configurator() config.include('ptah') PTAH_CFG = config.get_settings(ptah.CFG_ID_PTAH) """ return config.get_cfg_storage(ID_SETTINGS_GROUP)[grp]
def get_type(uri): """ :param uri: string identifier for TypeInformation, e.g. `cms-type:sqlblob` :Returns: - :py:class:`ptah.cms.TypeInformation` """ return config.get_cfg_storage(TYPES_DIR_ID).get(uri)
def typeInfoResolver(uri): """Type resolver :Parameters: - type scheme, e.g. blob-sql :Returns: - :py:class:`ptah.TypeInformation` """ return config.get_cfg_storage(TYPES_DIR_ID).get(uri)
def Api(request): """ Rest API interface """ response = request.response # authentication by token token = request.environ.get('HTTP_X_AUTH_TOKEN') if token: secret = ptah.get_settings(ptah.CFG_ID_PTAH, request.registry)['secret'] try: timestamp, userid, tokens, user_data = parse_ticket( secret, '%s!' % token, '0.0.0.0') except BadTicket: userid = None if userid: ptah.auth_service.set_userid(userid) # search service and action service = request.matchdict['service'] subpath = request.matchdict['subpath'] if subpath: action = subpath[0] arguments = subpath[1:] if ':' in action: action, arg = action.split(':', 1) arguments = (arg,) + arguments else: action = 'apidoc' arguments = () request.environ['SCRIPT_NAME'] = '/__rest__/%s' % service response.headerslist = {'Content-Type': 'application/json'} # execute action for specific service try: result = config.get_cfg_storage(ID_REST)[service]( request, action, *arguments) except WSGIHTTPException as exc: response.status = exc.status result = {'message': str(exc)} except Exception as exc: response.status = 500 out = NativeIO() traceback.print_exc(file=out) result = {'message': str(exc), 'traceback': out.getvalue()} if isinstance(result, Response): return result response.text = text_( dumps(result, indent=True, default=dthandler), 'utf-8') return response
def authenticate_principal(self, principal): info = AuthInfo(principal) for checker in \ config.get_cfg_storage(AUTH_CHECKER_ID).values(): if not checker(info): return info info.status = True return info
def test_rest_registerService(self): import ptah.rest srv = ptah.rest.RestService('test', 'Test service') self.init_ptah() services = config.get_cfg_storage(ptah.rest.ID_REST) self.assertEqual(srv.name, 'test') self.assertIn('test', services) self.assertIn(srv, services.values())