예제 #1
0
class ConfigGroups(OrderedFolder):

    class_id = 'config-groups'
    class_title = MSG(u'User Groups')
    class_description = MSG(u'Manage user groups.')
    class_icon48 = '/ui/ikaaro/icons/48x48/groups.png'

    # Configuration
    config_name = 'groups'
    config_group = 'access'
    property_name = 'groups'

    # Views
    class_views = ['browse_content', 'add_group', 'edit', 'commit_log']
    browse_content = BrowseGroups()
    add_group = NewResource_Local(title=MSG(u'Add group'))

    default_groups = [('admins', {
        'en': u'Admins'
    }), ('reviewers', {
        'en': u'Reviewers'
    }), ('members', {
        'en': u'Members'
    })]

    def init_resource(self, **kw):
        super(ConfigGroups, self).init_resource(**kw)
        # Add default groups
        for name, title in self.default_groups:
            self.make_resource(name, Group, title=title)

    def get_document_types(self):
        return [Group]
예제 #2
0
class ConfigModels(Folder):

    class_id = 'config-models'
    class_title = MSG(u'Content models')
    class_description = MSG(u'Define new types of content resources.')

    # Configuration
    config_name = 'models'
    config_group = 'content'

    # Views
    class_views = ['browse_content', 'add_model', 'edit', 'commit_log']
    browse_content = ConfigModels_Browse
    add_model = NewResource_Local(title=MSG(u'Add model'))

    def get_document_types(self):
        return [Model]
예제 #3
0
class ModelField_Choices(OrderedFolder, ModelField_Base):

    class_id = 'model-field-choices'
    class_title = MSG(u'Choices field')

    # Fields
    choices_widget = ChoicesWidget_Field(title=MSG(u'Widget to use'),
                                         required=True)

    def get_document_types(self):
        return [Choice]

    # API
    def build_field(self):
        options = [{
            'name': x.name,
            'value': x.get_title()
        } for x in self.get_resources_in_order()]
        field = Select_Field(widget=self.get_widget())
        field_kw = self.get_field_kw(field)
        return field(options=options, **field_kw)

    def get_widget(self):
        if self.get_value('choices_widget') == 'radio-checkbox':
            if self.get_value('multiple'):
                return CheckboxWidget
            return RadioWidget
        return SelectWidget

    # Views
    class_views = ['browse_content', 'add_choice', 'edit', 'commit_log']
    browse_content = ModelField_Choices_Browse
    add_choice = NewResource_Local(title=MSG(u'Add choice'))

    _fields = ModelField_Base._fields + ['choices_widget']
    new_instance = ModelField_Base.new_instance(fields=_fields)
    edit = AutoEdit(fields=_fields)
예제 #4
0
class Model(OrderedFolder):

    class_id = '-model'
    class_title = MSG(u'Base model')
    class_description = MSG(u'...')

    # Fields
    title = Folder.title(required=True)

    # Views
    class_views = ['browse_content', 'add_field', 'edit', 'commit_log']
    browse_content = Model_Browse
    new_instance = Model_NewInstance
    add_field = NewResource_Local(title=MSG(u'Add field'))

    # Order configuration
    allow_to_unorder_items = True

    def get_document_types(self):
        return [ModelField_Standard, ModelField_Choices]

    @property
    def __fixed_handlers__(self):
        return []
        # XXX To allow ordering, resources should not be fixed handlers
        #return [ x.name for x in self.get_resources()
        #         if isinstance(x, ModelField_Inherited) ]

    def get_model_fields(self):
        """Return the resources that represent a field.
        """
        return [
            x for x in self.get_resources_in_order()
            if isinstance(x, ModelField_Base)
        ]

    def build_resource_class(self):
        # bases
        base_class = self.base_class
        bases = (base_class, )
        # dict
        title = self.get_value('title')
        class_dict = {
            'class_id': str(self.abspath),
            'class_title': MSG(title) if title else base_class.class_title,
            'fields_soft': True,  # dynamic classes are fragile
        }

        fields = []
        for field_name in base_class.fields:
            field = base_class.get_field(field_name)
            if field and field.readonly:
                fields.append(field_name)

        for resource in self.get_model_fields():
            field_name = resource.name
            if not isinstance(resource, ModelField_Inherited):
                class_dict[field_name] = resource.build_field()
            fields.append(field_name)
        class_dict['fields'] = fields

        return type(self.name, bases, class_dict)

    def set_value(self, name, value, language=None):
        has_changed = super(Model, self).set_value(name, value, language)
        if has_changed:
            class_id = str(self.abspath)
            self.database._resources_registry.pop(class_id, None)

        return has_changed
예제 #5
0
class ConfigAccess(Folder):

    class_id = 'config-access'
    class_version = '20110606'
    class_title = MSG(u'Access Control')
    class_description = MSG(u'Choose the security policy.')
    class_icon48 = 'icons/48x48/lock.png'

    # Configuration
    config_name = 'access'
    config_group = 'access'

    # Initialization
    _everything = freeze({'path': '/', 'path_depth': '*'})
    default_rules = [
        # Everybody can see the theme
        ('everybody', 'view', {
            'path': '/config/theme',
            'path_depth': '*'
        }),
        # Authenticated users can see any content
        ('authenticated', 'view', _everything),
        # Members can add new content and edit private content
        ('/config/groups/members', 'add', _everything),
        ('/config/groups/members', 'edit', _everything),
        # Reviewers can add new content, edit any content and publish
        ('/config/groups/reviewers', 'add', _everything),
        ('/config/groups/reviewers', 'edit', _everything),
        ('/config/groups/reviewers', 'share', _everything)
    ]

    def init_resource(self, **kw):
        super(ConfigAccess, self).init_resource(**kw)
        # Access rules
        rules = self.default_rules
        for group, permission, kw in rules:
            rule = self.make_resource(None, AccessRule, group=group)
            rule.set_value('permission', permission)
            for key in kw:
                rule.set_value('search_%s' % key, kw[key])

    # API
    def _get_user_groups(self, user):
        user_groups = set(['everybody'])
        if user:
            user_groups.add('authenticated')
            user_groups.update(user.get_value('groups'))

        return user_groups, '/config/groups/admins' in user_groups

    def get_search_query(self, user, permission, class_id=None):
        # Special case: admins can see everything
        user_groups, is_admin = self._get_user_groups(user)
        if is_admin:
            return AllQuery()

        # 1. Back-office access rules
        rules_query = OrQuery()
        for rule in self.get_resources():
            if rule.get_value('permission') != permission:
                continue

            if rule.get_value('group') not in user_groups:
                continue

            if permission == 'add':
                r_format = rule.get_value('search_format')
                if class_id and r_format and class_id != r_format:
                    continue

            rules_query.append(rule.get_search_query())

        # Case: anonymous
        if not user:
            return AndQuery(rules_query, PhraseQuery('share', 'everybody'))

        # Case: authenticated
        share_query = OrQuery(*[PhraseQuery('share', x) for x in user_groups])
        share_query.append(PhraseQuery('share', str(user.abspath)))
        query = AndQuery(rules_query, share_query)

        if permission != 'share':
            return OrQuery(PhraseQuery('owner', str(user.abspath)), query)

        return query

    def has_permission(self, user, permission, resource, class_id=None):
        # The query
        query = AndQuery(self.get_search_query(user, permission, class_id),
                         PhraseQuery('abspath', str(resource.abspath)))

        # Search
        results = get_context().search(query)
        return len(results) > 0

    def get_document_types(self):
        return [AccessRule]

    # Views
    class_views = ['browse_content', 'add_rule', 'edit', 'commit_log']
    browse_content = ConfigAccess_Browse
    add_rule = NewResource_Local(title=MSG(u'Add rule'))