Exemplo n.º 1
0
    def location_breadcrumbs(self, fqname):
        """
        Split the incoming fqname into segments. Reassemble into a list of tuples.
        If the fqname has a namespace, the first tuple's segment_name will have the
        namespace as a prefix.

        :rtype: list
        :returns: location breadcrumbs items in tuple (segment_name, fq_name, exists)
        """
        breadcrumbs = []
        current_item = ''
        if not isinstance(fqname, CompositeName):
            fqname = split_fqname(fqname)
        if fqname.field != NAME_EXACT:
            return [
                (fqname, fqname, bool(self.storage.get_item(**fqname.query)))
            ]  # flaskg.unprotected_storage.get_item(**fqname.query)
        namespace = segment1_namespace = fqname.namespace
        item_name = fqname.value
        if not item_name:
            return breadcrumbs
        for segment in item_name.split('/'):
            current_item += segment
            fq_current = CompositeName(namespace, NAME_EXACT, current_item)
            fq_segment = CompositeName(segment1_namespace, NAME_EXACT, segment)
            breadcrumbs.append(
                (fq_segment, fq_current,
                 bool(self.storage.get_item(**fq_current.query))))
            current_item += '/'
            segment1_namespace = ''
        return breadcrumbs
Exemplo n.º 2
0
def gen_fqnames(meta):
    """Generate fqnames from meta data."""
    if meta[NAME]:
        return [
            CompositeName(meta[NAMESPACE], NAME_EXACT, name)
            for name in meta[NAME]
        ]
    return [CompositeName(meta[NAMESPACE], ITEMID, meta[ITEMID])]
Exemplo n.º 3
0
def item_acl_report():
    """
    Return a sorted list of all items in the wiki along with the ACL Meta-data.

    Item names are prefixed with the namespace, if there is a non-default namespace.
    If there are multiple names, the first name is used for sorting.
    """
    query = And([
        Term(WIKINAME, app.cfg.interwikiname),
        Not(Term(NAMESPACE, NAMESPACE_USERPROFILES)),
    ])
    all_items = flaskg.storage.search_meta(query,
                                           idx_name=LATEST_REVS,
                                           sortedby=[NAMESPACE, NAME],
                                           limit=None)
    items_acls = []
    for item in all_items:
        item_namespace = item.meta.get(NAMESPACE)
        item_id = item.meta.get(ITEMID)
        if item_namespace:
            item_name = [
                item_namespace + '/' + name for name in item.meta.get(NAME)
            ]
        else:
            item_name = item.meta.get(NAME)
        item_acl = item.meta.get(ACL)
        acl_default = item_acl is None
        if acl_default:
            for namespace, acl_config in app.cfg.acl_mapping:
                if item_namespace == namespace:
                    item_acl = acl_config['default']
        if item.meta.get(NAME):
            fqnames = [
                CompositeName(item.meta[NAMESPACE], NAME_EXACT, name)
                for name in item.meta[NAME]
            ]
        else:
            fqnames = [
                CompositeName(item.meta[NAMESPACE], ITEMID, item.meta[ITEMID])
            ]
        fqname = fqnames[0]
        items_acls.append({
            'name': item_name,
            'name_old': item.meta.get('name_old', []),
            'itemid': item_id,
            'fqnames': fqnames,
            'fqname': fqnames[0],
            'acl': item_acl,
            'acl_default': acl_default
        })
    # deleted items have no names; this sort places deleted items on top of the report;
    # the display name may be similar to: "9cf939f ~(DeletedItemName)"
    items_acls = sorted(items_acls, key=lambda k: (k['name'], k['name_old']))
    return render_template('admin/item_acl_report.html',
                           title_name=_('Item ACL Report'),
                           number_items=len(items_acls),
                           items_acls=items_acls)
Exemplo n.º 4
0
    def make_flat_index(self, subitems, isglobalindex=False):
        """
        Create two IndexEntry lists - ``dirs`` and ``files`` - from a list of
        subitems.

        Direct subitems are added to the ``files`` list.

        For indirect subitems, its ancestor which is a direct subitem is added
        to the ``dirs`` list. Supposing current index root is 'foo' and when
        'foo/bar/la' is encountered, 'foo/bar' is added to ``dirs``.

        The direct subitem need not exist.

        When both a subitem itself and some of its subitems are in the subitems
        list, it appears in both ``files`` and ``dirs``.

        :param isglobalindex: True if the query is for global indexes.
        """
        prefixes = [u''] if isglobalindex else self.subitem_prefixes
        # IndexEntry instances of "file" subitems
        files = []
        # IndexEntry instances of "directory" subitems
        dirs = []
        added_dir_relnames = set()
        for rev in subitems:
            fullnames = rev.meta[NAME]
            for fullname in fullnames:
                prefix = self.get_prefix_match(fullname, prefixes)
                if prefix is not None:
                    fullname_fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, fullname)
                    relname = fullname[len(prefix):]
                    if '/' in relname:
                        # Find the *direct* subitem that is the ancestor of current
                        # (indirect) subitem. e.g. suppose when the index root is
                        # 'foo', and current item (`rev`) is 'foo/bar/lorem/ipsum',
                        # 'foo/bar' will be found.
                        direct_relname = relname.partition('/')[0]
                        direct_relname_fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, direct_relname)
                        if direct_relname_fqname not in added_dir_relnames:
                            added_dir_relnames.add(direct_relname_fqname)
                            direct_fullname = prefix + direct_relname
                            direct_fullname_fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, direct_fullname)
                            fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, direct_fullname)
                            try:
                                direct_rev = get_storage_revision(fqname)
                            except AccessDenied:
                                continue  # user has permission to see parent, but not this subitem
                            dirs.append(IndexEntry(direct_relname, direct_fullname_fqname, direct_rev.meta))
                    else:
                        files.append(IndexEntry(relname, fullname_fqname, rev.meta))
        files.sort()  # files with multiple names are not in sequence
        return dirs, files
Exemplo n.º 5
0
 def get_namespaces(self, ns=None):
     """
     Return the list of tuples (composite name, namespace) referring to namespaces other
     than the current namespace.
     """
     if ns is not None and ns.value == '~':
         ns = u''
     namespace_root_mapping = []
     for namespace, _unused in app.cfg.namespace_mapping:
         namespace = namespace.rstrip('/')
         if ns is None or namespace != ns:
             fq_namespace = CompositeName(namespace, NAME_EXACT, u'')
             namespace_root_mapping.append((namespace or '~', fq_namespace.get_root_fqname()))
     return namespace_root_mapping
Exemplo n.º 6
0
def user_acl_report(uid):
    query = And([
        Term(WIKINAME, app.cfg.interwikiname),
        Not(Term(NAMESPACE, NAMESPACE_USERPROFILES))
    ])
    all_items = flaskg.storage.search_meta(query,
                                           idx_name=LATEST_REVS,
                                           sortedby=[NAMESPACE, NAME],
                                           limit=None)
    theuser = user.User(uid=uid)
    itemwise_acl = []
    last_item_acl_parts = (None, None, None)
    last_item_result = {
        'read': False,
        'write': False,
        'create': False,
        'admin': False,
        'destroy': False
    }
    for item in all_items:
        if item.meta.get(NAME):
            fqname = CompositeName(item.meta.get(NAMESPACE), NAME_EXACT,
                                   item.meta.get(NAME)[0])
        else:
            fqname = CompositeName(item.meta.get(NAMESPACE), ITEMID,
                                   item.meta.get(ITEMID))
        this_rev_acl_parts = (item.meta[NAMESPACE], item.meta.get(PARENTNAMES),
                              item.meta.get(ACL))
        name_parts = {
            'name': item.meta.get(NAME),
            'namespace': item.meta.get(NAMESPACE),
            'itemid': item.meta.get(ITEMID),
            'fqname': fqname
        }
        if not last_item_acl_parts == this_rev_acl_parts:
            last_item_acl_parts = this_rev_acl_parts
            last_item_result = {
                'read': theuser.may.read(fqname),
                'write': theuser.may.write(fqname),
                'create': theuser.may.create(fqname),
                'admin': theuser.may.admin(fqname),
                'destroy': theuser.may.destroy(fqname)
            }
        itemwise_acl.append({**name_parts, **last_item_result})
    return render_template('admin/user_acl_report.html',
                           title_name=_('User ACL Report'),
                           user_names=theuser.name,
                           itemwise_acl=itemwise_acl)
Exemplo n.º 7
0
    def do_modify(self):
        """
        Process new ticket, changes to ticket meta data, and/or a new comment against original ticket description.

        User has clicked "Submit ticket" or "Update ticket" button to get here. If user clicks Save button to
        add a comment to a prior comment it is not processed here - see /+comment in views.py.
        """
        is_new = isinstance(self.content, NonExistentContent)
        closed = self.meta.get('closed')

        Form = TicketSubmitForm if is_new else TicketUpdateForm

        if request.method in ['GET', 'HEAD']:
            form = Form.from_item(self)
        elif request.method == 'POST':
            form = Form.from_request(request)
            if form.validate():
                meta, data, message, data_file = form._dump(self)  # saves new ticket revision if ticket meta has changed
                try:
                    if not is_new and message:
                        # user created a new comment
                        create_comment(self.meta, message)
                    if is_new:
                        self.modify(meta, data)
                    if data_file:
                        file_upload(self, data_file)
                except AccessDenied:
                    abort(403)
                else:
                    try:
                        fqname = CompositeName(self.meta[NAMESPACE], ITEMID, self.meta[ITEMID])
                    except KeyError:
                        fqname = self.fqname
                    return redirect(url_for('.show_item', item_name=fqname))
        if is_new:
            data_rendered = None
            files = {}
            roots = []
            comments = {}
        else:
            data_rendered = Markup(self.content._render_data())
            files = get_files(self)
            comments, roots = get_comments(self)
        suggested_tags = get_itemtype_specific_tags(ITEMTYPE_TICKET)
        ordered_comments = []  # list of tuples [(comment, indent),,, ]
        for root in roots:
            ordered_comments += [(root, 0), ] + build_tree(comments, root, [], 0)
        return render_template(self.submit_template if is_new else self.modify_template,
                               is_new=is_new,
                               closed=closed,
                               item_name=self.name,
                               data_rendered=data_rendered,
                               form=form,
                               suggested_tags=suggested_tags,
                               item=self,
                               files=files,
                               datetime=datetime.datetime,
                               ordered_comments=ordered_comments,
                               render_comment_data=render_comment_data,
                              )
Exemplo n.º 8
0
def group_acl_report(group_name):
    """
    Display a 2-column table of items and ACLs, where the ACL rule specifies any
    WikiGroup or ConfigGroup name.
    """
    group = search_group(group_name)
    all_items = flaskg.storage.documents(wikiname=app.cfg.interwikiname)
    group_items = []
    for item in all_items:
        acl_iterator = ACLStringIterator(ACL_RIGHTS_CONTENTS,
                                         item.meta.get(ACL, ''))
        for modifier, entries, rights in acl_iterator:
            if group_name in entries:
                item_id = item.meta.get(ITEMID)
                fqname = CompositeName(item.meta.get(NAMESPACE), u'itemid',
                                       item_id)
                group_items.append(
                    dict(name=item.meta.get(NAME),
                         itemid=item_id,
                         fqname=fqname,
                         rights=rights))
    return render_template('admin/group_acl_report.html',
                           title_name=_(u'Group ACL Report'),
                           group_items=group_items,
                           group_name=group_name)
Exemplo n.º 9
0
def build_dirs_index(basename, relnames):
    """
    Build a list of IndexEntry by hand, useful as a test helper for index testing.
    Dirs are files with subitems and have meta == {}.
    """
    return [(IndexEntry(relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join((basename, relname))), {}))
            for relname in relnames]
Exemplo n.º 10
0
 def __init__(self, protector, meta):
     """
     :param protector: protector middleware
     :param meta: meta data of item to protect
     """
     self.protector = protector
     self.meta = meta
     if meta[NAME]:
         self.fqnames = [
             CompositeName(meta[NAMESPACE], NAME_EXACT, name)
             for name in meta[NAME]
         ]
     else:
         self.fqnames = [
             CompositeName(meta[NAMESPACE], ITEMID, meta[ITEMID])
         ]
Exemplo n.º 11
0
 def _rename(self, name, comment, action, delete=False):
     self._save(self.meta,
                self.content.data,
                name=name,
                action=action,
                comment=comment,
                delete=delete)
     old_prefix = self.subitem_prefixes[0]
     old_prefixlen = len(old_prefix)
     if not delete:
         new_prefix = name + '/'
     for child in self.get_subitem_revs():
         for child_oldname in child.meta[NAME]:
             if child_oldname.startswith(old_prefix):
                 if delete:
                     child_newname = None
                 else:  # rename
                     child_newname = new_prefix + child_oldname[
                         old_prefixlen:]
                 old_fqname = CompositeName(self.fqname.namespace,
                                            self.fqname.field,
                                            child_oldname)
                 item = Item.create(old_fqname.fullname)
                 item._save(item.meta,
                            item.content.data,
                            name=child_newname,
                            action=action,
                            comment=comment,
                            delete=delete)
Exemplo n.º 12
0
def userbrowser():
    """
    User Account Browser
    """
    groups = flaskg.groups
    member_groups = {}  # {username: [list of groups], ...}
    for groupname in groups:
        group = groups[groupname]
        for member in group.members:
            member_groups[member] = member_groups.get(member,
                                                      []) + [group.name]

    revs = user.search_users()  # all users
    user_accounts = []
    for rev in revs:
        user_names = rev.meta[NAME]
        user_groups = member_groups.get(user_names[0], [])
        for name in user_names[1:]:
            user_groups = user_groups + member_groups.get(name, [])
        subscriptions = rev.meta[SUBSCRIPTIONS]
        user_accounts.append(
            dict(uid=rev.meta[ITEMID],
                 name=user_names,
                 fqname=CompositeName(NAMESPACE_USERS, NAME_EXACT, rev.name),
                 email=rev.meta[EMAIL]
                 if EMAIL in rev.meta else rev.meta[EMAIL_UNVALIDATED],
                 disabled=rev.meta[DISABLED],
                 groups=user_groups,
                 subscriptions=subscriptions))
    return render_template('admin/userbrowser.html',
                           user_accounts=user_accounts,
                           title_name=_("Users"))
Exemplo n.º 13
0
def test_validjson():
    """
    Tests for changes to metadata when modifying an item.

    Does not apply to usersettings form.
    """
    app.cfg.namespace_mapping = [(u'', 'default_backend'), (u'ns1/', 'default_backend'), (u'users/', 'other_backend')]
    item = Item.create(u'users/existingname')
    meta = {NAMESPACE: u'users', CONTENTTYPE: u'text/plain;charset=utf-8'}
    become_trusted()
    item._save(meta, data='This is a valid Item.')

    valid_itemid = 'a1924e3d0a34497eab18563299d32178'
    # ('names', 'namespace', 'field', 'value', 'result')
    tests = [([u'somename', u'@revid'], '', '', 'somename', False),  # item names cannot begin with @
             # TODO for above? - create item @x, get error message, change name in meta to xx, get an item with names @40x and alias of xx
             ([u'bar', u'ns1'], '', '', 'bar', False),  # item names cannot match namespace names
             ([u'foo', u'foo', u'bar'], '', '', 'foo', False),  # names in the name list must be unique.
             ([u'ns1ns2ns3', u'ns1/subitem'], '', '', 'valid', False),  # Item names must not match with existing namespaces; items cannot be in 2 namespaces
             ([u'foobar', u'validname'], '', ITEMID, valid_itemid + '8080', False),  # attempts to change itemid in meta result in "Item(s) named foobar, validname already exist."
             ([u'barfoo', u'validname'], '', ITEMID, valid_itemid.replace('a', 'y'), False),  # similar to above
             ([], '', 'itemid', valid_itemid, True),  # deleting all names from the metadata of an existing item will make it nameless, succeeds
             ([u'existingname'], 'users', '', 'existingname', False),  # item already exists
            ]
    for name, namespace, field, value, result in tests:
        meta = {NAME: name, NAMESPACE: namespace}
        x = JSON(json.dumps(meta))
        y = Names(name)
        state = dict(fqname=CompositeName(namespace, field, value), itemid=None, meta=meta)
        value = x.validate(state) and y.validate(state)
        assert value == result
Exemplo n.º 14
0
    def test_user(self):
        meta = {
            keys.ITEMID:
            make_uuid(),
            keys.REVID:
            make_uuid(),
            keys.NAME: [
                u"user name",
            ],
            keys.NAMESPACE:
            u"userprofiles",
            keys.EMAIL:
            u"*****@*****.**",
            keys.SUBSCRIPTIONS: [
                u"{0}:{1}".format(keys.ITEMID, make_uuid()),
                u"{0}::foo".format(keys.NAME),
                u"{0}::bar".format(keys.TAGS),
                u"{0}::".format(keys.NAMERE),
                u"{0}:userprofiles:a".format(keys.NAMEPREFIX),
            ]
        }

        invalid_meta = {
            keys.SUBSCRIPTIONS: [
                u"",
                u"unknown_tag:123",
                u"{0}:123".format(keys.ITEMID),
                u"{0}:foo".format(keys.NAME),
            ]
        }

        state = {
            'trusted':
            False,  # True for loading a serialized representation or other trusted sources
            keys.NAME: u'somename',  # name we decoded from URL path
            keys.ACTION: keys.ACTION_SAVE,
            keys.HOSTNAME: u'localhost',
            keys.ADDRESS: u'127.0.0.1',
            keys.WIKINAME: u'ThisWiki',
            keys.NAMESPACE: u'',
            keys.FQNAME: CompositeName(u'', u'', u'somename')
        }

        m = UserMetaSchema(meta)
        valid = m.validate(state)
        assert m[keys.CONTENTTYPE].value == CONTENTTYPE_USER
        if not valid:
            for e in m.children:
                print e.valid, e
            print m.valid, m
        assert valid

        m = UserMetaSchema(invalid_meta)
        valid = m.validate(state)
        assert not valid
        for e in m.children:
            if e.name in (keys.SUBSCRIPTIONS, ):
                for value in e:
                    assert not value.valid
Exemplo n.º 15
0
def build_mixed_index(basename, spec):
    """
    Build a list of MixedIndexEntry by hand, useful as a test helper.

    :spec is a list of (relname, hassubitem) tuples.
    """
    return [(MixedIndexEntry(relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join((basename, relname))), Item.create('/'.join((basename, relname))).meta, hassubitem))
            for relname, hassubitem in spec]
Exemplo n.º 16
0
def build_index(basename, relnames):
    """
    Build a list of IndexEntry by hand, useful as a test helper for index testing.
    Files have no subitems, meta content is reduced to required keys.
    """
    files = [(IndexEntry(relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join((basename, relname))), Item.create('/'.join((basename, relname))).meta))
            for relname in relnames]
    return [(IndexEntry(f.relname, f.fullname, {key: f.meta[key] for key in (CONTENTTYPE, ITEMTYPE)}))
            for f in files]
Exemplo n.º 17
0
def build_index(basename, relnames):
    """
    Build a list of IndexEntry by hand, useful as a test helper.
    """
    return [(IndexEntry(
        relname,
        CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join(
            (basename, relname))),
        Item.create('/'.join((basename, relname))).meta))
            for relname in relnames]
Exemplo n.º 18
0
def _trashed(namespace):
    q = And([Term(WIKINAME, app.cfg.interwikiname), Term(TRASH, True)])
    if namespace != NAMESPACE_ALL:
        q = And([q, Term(NAMESPACE, namespace), ])
    trashedEntry = namedtuple('trashedEntry', 'fqname oldname revid rev_number mtime comment editor parentid')
    results = []
    for meta in flaskg.storage.search_meta(q, limit=None):
        fqname = CompositeName(meta[NAMESPACE], ITEMID, meta[ITEMID])
        results.append(trashedEntry(fqname, meta[NAME_OLD], meta[REVID], meta[REV_NUMBER], meta[MTIME], meta[COMMENT], get_editor_info(meta), meta[PARENTID]))
    return results
Exemplo n.º 19
0
 def rename(self, name, comment=u''):
     """
     rename this item to item <name> (replace current name by another name in the NAME list)
     """
     fqname = CompositeName(self.fqname.namespace, self.fqname.field, name)
     if flaskg.storage.get_item(**fqname.query):
         raise NameNotUniqueError(L_("An item named %s already exists in the namespace %s." % (name, fqname.namespace)))
     # if this is a subitem, verify all parent items exist
     _verify_parents(self, name, self.fqname.namespace, old_name=self.fqname.value)
     return self._rename(name, comment, action=ACTION_RENAME)
Exemplo n.º 20
0
def _verify_parents(self, new_name, namespace, old_name=''):
    """
    If this is a subitem, verify all parent items exist. Return None if OK, raise error if not OK.
    """
    name_segments = new_name.split('/')
    for idx in range(len(name_segments) - 1):
        root_name = '/'.join(name_segments[:idx + 1])
        fqname = CompositeName(namespace, NAME_EXACT, root_name)
        parent_item = flaskg.unprotected_storage.get_item(**fqname.query)
        if parent_item.itemid is None:
            raise MissingParentError(_("Cannot create or rename item '%(new_name)s' because parent '%(parent_name)s' is missing.", new_name=new_name, parent_name=name_segments[idx]))
Exemplo n.º 21
0
    def split_navilink(self, text):
        """
        Split navibar links into pagename, link to page

        Admin or user might want to use shorter navibar items by using
        the [[page|title]] or [[url|title]] syntax.

        Supported syntax:
            * PageName
            * WikiName:PageName
            * wiki:WikiName:PageName
            * url
            * all targets as seen above with title: [[target|title]]

        :param text: the text used in config or user preferences
        :rtype: tuple
        :returns: pagename or url, link to page or url
        """
        title = None
        wiki_local = ''  # means local wiki

        # Handle [[pagename|title]] or [[url|title]] formats
        if text.startswith('[[') and text.endswith(']]'):
            text = text[2:-2]
            try:
                target, title = text.split('|', 1)
                target = target.strip()
                title = title.strip()
            except (ValueError, TypeError):
                # Just use the text as is.
                target = text.strip()
        else:
            target = text

        if wikiutil.is_URL(target):
            if not title:
                title = target
            return target, title, wiki_local

        # remove wiki: url prefix
        if target.startswith("wiki:"):
            target = target[5:]

        wiki_name, namespace, field, item_name = split_interwiki(target)
        if wiki_name == 'Self':
            wiki_name = ''
        href = url_for_item(item_name,
                            namespace=namespace,
                            wiki_name=wiki_name,
                            field=field)
        if not title:
            title = shorten_fqname(CompositeName(namespace, field, item_name))
        return href, title, wiki_name
Exemplo n.º 22
0
def build_mixed_index(basename, spec):
    """
    Build a list of MixedIndexEntry by hand, useful as a test helper for index testing.
    The mixed index is a combo of dirs and files with empty meta (dirs) or reduced
    meta (files).

    :spec is a list of (relname, hassubitem) tuples.
    """
    files = [(MixedIndexEntry(relname, CompositeName(NAMESPACE_DEFAULT, NAME_EXACT, '/'.join((basename, relname))), Item.create('/'.join((basename, relname))).meta, hassubitem))
            for relname, hassubitem in spec]
    return [(MixedIndexEntry(f.relname, f.fullname, {} if f.hassubitems else {key: f.meta[key] for key in (CONTENTTYPE, ITEMTYPE)}, f.hassubitems))
            for f in files]
Exemplo n.º 23
0
def get_subscribers(**meta):
    """ Get all users that are subscribed to the item

    :param meta: key/value pairs from item metadata - itemid, name, namespace, tags keys
    :return: a set of Subscriber objects
    """
    itemid = meta.get(ITEMID)
    name = meta.get(NAME)
    namespace = meta.get(NAMESPACE)
    fqname = CompositeName(namespace, ITEMID, itemid)
    tags = meta.get(TAGS)
    terms = []
    if itemid is not None:
        terms.extend(
            [Term(SUBSCRIPTION_IDS, "{0}:{1}".format(ITEMID, itemid))])
    if namespace is not None:
        if name is not None:
            terms.extend(
                Term(SUBSCRIPTION_IDS, "{0}:{1}:{2}".format(
                    NAME, namespace, name_)) for name_ in name)
        if tags is not None:
            terms.extend(
                Term(SUBSCRIPTION_IDS, "{0}:{1}:{2}".format(
                    TAGS, namespace, tag)) for tag in tags)
    query = Or(terms)
    with flaskg.storage.indexer.ix[LATEST_REVS].searcher() as searcher:
        result_iterators = [
            searcher.search(query, limit=None),
        ]
        subscription_patterns = searcher.lexicon(SUBSCRIPTION_PATTERNS)
        # looks like whoosh gives us bytes (not str), decode them:
        subscription_patterns = [
            p if isinstance(p, str) else p.decode()
            for p in subscription_patterns
        ]
        patterns = get_matched_subscription_patterns(subscription_patterns,
                                                     **meta)
        result_iterators.extend(
            searcher.documents(subscription_patterns=pattern)
            for pattern in patterns)
        subscribers = set()
        for user in chain.from_iterable(result_iterators):
            email = user.get(EMAIL)
            if email:
                from moin.user import User
                u = User(uid=user.get(ITEMID))
                if u.may.read(fqname):
                    locale = user.get(LOCALE, DEFAULT_LOCALE)
                    subscribers.add(
                        Subscriber(user[ITEMID], user[NAME][0], email, locale))
    return subscribers
Exemplo n.º 24
0
def itemsize():
    """display a table with item sizes"""
    headings = [
        _('Size'),
        _('Item name'),
    ]
    query = And([Term(WIKINAME, app.cfg.interwikiname), Not(Term(NAMESPACE, NAMESPACE_USERPROFILES)), Not(Term(TRASH, True))])
    revs = flaskg.storage.search_meta(query, idx_name=LATEST_REVS, sortedby=[NAME], limit=None)
    rows = [(rev[SIZE], CompositeName(rev[NAMESPACE], NAME_EXACT, rev[NAME][0]))
            for rev in revs]
    rows = sorted(rows, reverse=True)
    return render_template('user/itemsize.html',
                           title_name=_("Item Sizes"),
                           headings=headings,
                           rows=rows)
Exemplo n.º 25
0
def group_acl_report(group_name):
    """
    Display a table of items and permissions, where the ACL rule specifies any
    WikiGroup or ConfigGroup name.
    """
    query = And([
        Term(WIKINAME, app.cfg.interwikiname),
        Not(Term(NAMESPACE, NAMESPACE_USERPROFILES))
    ])
    all_items = flaskg.storage.search_meta(query,
                                           idx_name=LATEST_REVS,
                                           sortedby=[NAMESPACE, NAME],
                                           limit=None)
    group_items = []
    for item in all_items:
        acl_iterator = ACLStringIterator(ACL_RIGHTS_CONTENTS,
                                         item.meta.get(ACL, ''))
        for modifier, entries, rights in acl_iterator:
            if group_name in entries:
                if item.meta.get(NAME):
                    fqname = CompositeName(item.meta.get(NAMESPACE),
                                           NAME_EXACT,
                                           item.meta.get(NAME)[0])
                else:
                    fqname = CompositeName(item.meta.get(NAMESPACE), ITEMID,
                                           item.meta.get(ITEMID))
                group_items.append(
                    dict(name=item.meta.get(NAME),
                         itemid=item.meta.get(ITEMID),
                         namespace=item.meta.get(NAMESPACE),
                         fqname=fqname,
                         rights=rights))
    return render_template('admin/group_acl_report.html',
                           title_name=_('Group ACL Report'),
                           group_items=group_items,
                           group_name=group_name)
Exemplo n.º 26
0
    def test_content(self):
        class REV(dict):
            """ fake rev """

        rev = REV()
        rev[keys.ITEMID] = make_uuid()
        rev[keys.REVID] = make_uuid()
        rev[keys.ACL] = u"All:read"

        meta = {
            keys.REVID: make_uuid(),
            keys.PARENTID: make_uuid(),
            keys.NAME: [
                u"a",
            ],
            keys.NAMESPACE: u"",
            keys.ACL: u"All:read",
            keys.TAGS: [u"foo", u"bar"],
        }

        state = {
            'trusted':
            False,  # True for loading a serialized representation or other trusted sources
            keys.NAME: u'somename',  # name we decoded from URL path
            keys.ACTION: keys.ACTION_SAVE,
            keys.HOSTNAME: u'localhost',
            keys.ADDRESS: u'127.0.0.1',
            keys.USERID: make_uuid(),
            keys.HASH_ALGORITHM: u'b9064b9a5efd8c6cef2d38a8169a0e1cbfdb41ba',
            keys.SIZE: 0,
            keys.WIKINAME: u'ThisWiki',
            keys.NAMESPACE: u'',
            'rev_parent': rev,
            'acl_parent': u"All:read",
            'contenttype_current': u'text/x.moin.wiki;charset=utf-8',
            'contenttype_guessed': u'text/plain;charset=utf-8',
            keys.FQNAME: CompositeName(u'', u'', u'somename'),
        }

        m = ContentMetaSchema(meta)
        valid = m.validate(state)
        assert m[keys.CONTENTTYPE].value == u'text/x.moin.wiki;charset=utf-8'
        if not valid:
            for e in m.children:
                print e.valid, e
            print m.valid, m
        assert valid
Exemplo n.º 27
0
 def __call__(self, rev, contenttype=None, arguments=None):
     fqname = CompositeName(rev.meta[NAMESPACE], NAME_EXACT, rev.meta[NAME][0])
     self.fullname = fqname.fullname
     try:
         contents = self.list_contents(rev.data)
         contents = [(self.process_size(size),
                      self.process_datetime(dt),
                      self.process_name(name),
                      ) for size, dt, name in contents]
         table = self.build_dom_table(contents, head=[_("Size"), _("Timestamp"), _("Name")], cls='zebra')
         body = moin_page.body(children=(table, ))
         return moin_page.page(children=(body, ))
     except ArchiveException as err:
         logging.exception("An exception within archive file handling occurred:")
         # XXX we also use a table for error reporting, could be
         # something more adequate, though:
         return self.build_dom_table([[str(err)]])
Exemplo n.º 28
0
def get_files(self):
    check_itemid(self)
    if self.meta.get(ITEMID) and self.meta.get(NAME):
        refers_to = self.meta[ITEMID]
        prefix = self.meta[ITEMID] + '/'
    else:
        refers_to = self.fqname.value
        prefix = self.fqname.value + '/'
    query = And([Term(WIKINAME, app.cfg.interwikiname), Term(REFERS_TO, refers_to), Term(ELEMENT, u'file')])
    revs = flaskg.storage.search(query, limit=None)
    files = []
    for rev in revs:
        names = rev.meta[NAME]
        for name in names:
            relname = name[len(prefix):]
            file_fqname = CompositeName(rev.meta[NAMESPACE], ITEMID, rev.meta[ITEMID])
            files.append(IndexEntry(relname, file_fqname, rev.meta))
    return files
Exemplo n.º 29
0
def user_acl_report(uid):
    all_items = flaskg.storage.documents(wikiname=app.cfg.interwikiname)
    groups = flaskg.groups
    theuser = user.User(uid=uid)
    itemwise_acl = []
    for item in all_items:
        fqname = CompositeName(item.meta.get(NAMESPACE), 'itemid', item.meta.get(ITEMID))
        itemwise_acl.append({'name': item.meta.get(NAME),
                             'itemid': item.meta.get(ITEMID),
                             'fqname': fqname,
                             'read': theuser.may.read(fqname),
                             'write': theuser.may.write(fqname),
                             'create': theuser.may.create(fqname),
                             'admin': theuser.may.admin(fqname),
                             'destroy': theuser.may.destroy(fqname)})
    return render_template('admin/user_acl_report.html',
                           title_name=_('User ACL Report'),
                           user_names=theuser.name,
                           itemwise_acl=itemwise_acl)
Exemplo n.º 30
0
    def path_breadcrumbs(self):
        """
        Assemble the path breadcrumbs (a.k.a.: trail)

        :rtype: list
        :returns: path breadcrumbs items in tuple (wiki_name, item_name, url, exists, err)
        """
        user = self.user
        breadcrumbs = []
        trail = user.get_trail()
        for interwiki_item_name in trail:
            wiki_name, namespace, field, item_name = split_interwiki(interwiki_item_name)
            fqname = CompositeName(namespace, field, item_name)
            err = not is_known_wiki(wiki_name)
            href = url_for_item(wiki_name=wiki_name, **fqname.split)
            if is_local_wiki(wiki_name):
                exists = bool(self.storage.get_item(**fqname.query))
                wiki_name = ''  # means "this wiki" for the theme code
            else:
                exists = True  # we can't detect existance of remote items
            if item_name:
                breadcrumbs.append((wiki_name, fqname, href, exists, err))
        return breadcrumbs