Esempio n. 1
0
 def render_registration_fields(self, req, data, fragments):
     self.log.debug("Adding registration check data fields")
     if self.replace_checks:
         for check in self.listeners:
             try:
                 if check.__class__.__name__ != 'RegistrationFilterAdapter':
                     self.log.debug("Add registration check data %s", check)
                     fragment, f_data = \
                         check.render_registration_fields(req, data)
                     try:
                         fragments['optional'] = \
                             tag(fragments.get('optional', ''),
                                 fragment.get('optional', ''))
                         fragments['required'] = \
                             tag(fragments.get('required', ''),
                                 fragment.get('required', ''))
                     except AttributeError:
                         if fragment is not None and fragment != '':
                             fragments['required'] = \
                                 tag(fragments.get('required', ''),
                                     fragment)
                     data.update(f_data)
             except Exception, e:
                 self.log.exception("Adding registration fields failed: %s",
                                    e)
    def render_registration_fields(self, req, data):
        """Add a hidden text input field to the registration form, and
        a visible one with mandatory input as well, if token is configured.
        """
        if self.reg_basic_token:
            # Preserve last input for editing on failure instead of typing
            # everything again.
            old_value = req.args.get('basic_token', '')

            if self.reg_basic_question:
                # TRANSLATOR: Question-style hint for visible bot trap
                # registration input field.
                hint = tag.p(_("Please answer above: %(question)s",
                               question=self.reg_basic_question),
                             class_='hint')
            else:
                # TRANSLATOR: Verbatim token hint for visible bot trap
                # registration input field.
                hint = tag.p(tag_(
                    "Please type [%(token)s] as verification token, "
                    "exactly replicating everything within the braces.",
                    token=tag.b(self.reg_basic_token)), class_='hint')
            insert = tag(
                tag.label(_("Parole:"),
                          tag.input(type='text', name='basic_token', size=20,
                                    class_='textwidget', value=old_value)),
                hint)
        else:
            insert = None
        # TRANSLATOR: Registration form hint for hidden bot trap input field.
        insert = tag(insert,
                     tag.input(type='hidden', name='sentinel',
                               title=_("Better do not fill this field.")))
        return insert, data
 def render_registration_fields(self, req, data):
     """Add an email address text input field to the registration form."""
     # Preserve last input for editing on failure instead of typing
     # everything again.
     old_value = req.args.get('email', '').strip()
     insert = tag.label(_("Email:"),
                        tag.input(type='text', name='email', size=20,
                                  class_='textwidget', value=old_value))
     # Deferred import required to aviod circular import dependencies.
     from acct_mgr.web_ui import AccountModule
     reset_password = AccountModule(self.env).reset_password_enabled
     verify_account = self.env.is_enabled(EmailVerificationModule) and \
                      EmailVerificationModule(self.env).verify_email
     if verify_account:
         # TRANSLATOR: Registration form hints for a mandatory input field.
         hint = tag.p(_("""
             The email address is required for Trac to send you a
             verification token.
             """), class_='hint')
         if reset_password:
             hint = tag(hint, tag.p(_("""
                 Entering your email address will also enable you to reset
                 your password if you ever forget it.
                 """), class_='hint'))
         return tag(insert, hint), data
     elif reset_password:
         # TRANSLATOR: Registration form hint, if email input is optional.
         hint = tag.p(_("""Entering your email address will enable you to
                        reset your password if you ever forget it."""),
                      class_='hint')
         return dict(optional=tag(insert, hint)), data
     else:
         # Always return the email text input itself as optional field.
         return dict(optional=insert), data
    def validate_registration(self, req):
        if req.path_info == '/prefs':
            return

        acctmgr = AccountManager(self.env)
        username = acctmgr.handle_username_casing(
            req.args.get('username', '').strip())

        if not username:
            raise RegistrationError(N_("Username cannot be empty."))

        # Always exclude some special characters, i.e.
        #   ':' can't be used in HtPasswdStore
        #   '[' and ']' can't be used in SvnServePasswordStore
        blacklist = acctmgr.username_char_blacklist
        if contains_any(username, blacklist):
            pretty_blacklist = ''
            for c in blacklist:
                if pretty_blacklist == '':
                    pretty_blacklist = tag(' \'', tag.b(c), '\'')
                else:
                    pretty_blacklist = tag(pretty_blacklist,
                                           ', \'', tag.b(c), '\'')
            raise RegistrationError(N_(
                "The username must not contain any of these characters: %s"),
                tag.b(pretty_blacklist)
            )

        # All upper-cased names are reserved for permission action names.
        if username.isupper():
            raise RegistrationError(N_("A username with only upper-cased "
                                       "characters is not allowed."))

        # Prohibit some user names, that are important for Trac and therefor
        # reserved, even if not in the permission store for some reason.
        if username.lower() in ['anonymous', 'authenticated']:
            raise RegistrationError(N_("Username %s is not allowed."),
                                    tag.b(username))

        # NOTE: A user may exist in a password store but not in the permission
        #   store.  I.e. this happens, when the user (from the password store)
        #   never logged in into Trac.  So we have to perform this test here
        #   and cannot just check for the user being in the permission store.
        #   And better obfuscate whether an existing user or group name
        #   was responsible for rejection of this user name.
        for store_user in acctmgr.get_users():
            # Do it carefully by disregarding case.
            if store_user.lower() == username.lower():
                raise RegistrationError(tag_(
                    "Another account or group already exists, who's name "
                    "differs from %(username)s only by case or is identical.",
                    username=tag.b(username)))

        # Password consistency checks follow.
        password = req.args.get('password')
        if not password:
            raise RegistrationError(N_("Password cannot be empty."))
        elif password != req.args.get('password_confirm'):
            raise RegistrationError(N_("The passwords must match."))
Esempio n. 5
0
 def render(context, field, event):
     if event[0] == 'test&1':
         if field == 'url':
             return 'http://example.org/path?foo=bar&baz=1'
         if field == 'summary':
             return 'summary 1: <b>&</b>'
         if field == 'description':
             return tag(tag.h1('Title 1st'), tag.p('body & < >'))
     if event[0] == 'test&2':
         if field == 'url':
             return 'http://example.org/path?baz=2&foo=bar'
         if field == 'summary':
             return tag('summary 2: ', tag.b('&'))
         if field == 'description':
             return tag(tag.h1('Title 2nd'), tag.p('body & < >'))
Esempio n. 6
0
    def _do_update(self, req):
        """Update component enable state."""
        components = req.args.getlist('component')
        enabled = req.args.getlist('enable')
        added, removed = [], []

        # FIXME: this needs to be more intelligent and minimize multiple
        # component names to prefix rules

        for component in components:
            is_enabled = bool(self.env.is_component_enabled(component))
            must_enable = component in enabled
            if is_enabled != must_enable:
                self.config.set('components', component,
                                'disabled' if is_enabled else 'enabled')
                self.log.info("%sabling component %s",
                              "Dis" if is_enabled else "En", component)
                if must_enable:
                    added.append(component)
                else:
                    removed.append(component)

        if added or removed:
            def make_list(items):
                parts = [item.rsplit('.', 1) for item in items]
                return tag.table(tag.tbody(
                    tag.tr(tag.td(c, class_='trac-name'),
                           tag.td('(%s.*)' % m, class_='trac-name'))
                    for m, c in parts), class_='trac-pluglist')

            added.sort()
            removed.sort()
            notices = []
            if removed:
                msg = ngettext("The following component has been disabled:",
                               "The following components have been disabled:",
                               len(removed))
                notices.append(tag(msg, make_list(removed)))
            if added:
                msg = ngettext("The following component has been enabled:",
                               "The following components have been enabled:",
                               len(added))
                notices.append(tag(msg, make_list(added)))

            # set the default value of options for only the enabled components
            for component in added:
                self.config.set_defaults(component=component)
            _save_config(self.config, req, self.log, notices)
Esempio n. 7
0
    def _link_crashes_by_id(self, req, ids):
        items = []

        for i, word in enumerate(re.split(r'([;,\s]+)', ids)):
            if i % 2:
                items.append(word)
            elif word:
                crashid = word
                word = 'CrashId#%s' % word

                try:
                    crash = CrashDump(env=self.env, id=crashid)
                    word = \
                        tag.a(
                            'CrashId#%i' % crash.id,
                            class_=crash['status'],
                            href=req.href('crash', crash.uuid),
                            title=crash.uuid
                        )
                except ResourceNotFound:
                    pass
                items.append(word)

        if items:
            return tag(items)
        else:
            return None
Esempio n. 8
0
    def generate_captcha(self, req):
        session_id = "%d-3.4.0.001" % random.randint(1, 10000000)
        sign1 = hashlib.md5(session_id + req.remote_addr +
                            self.private_key).hexdigest()
        sign2 = hashlib.md5(session_id + self.private_key).hexdigest()
        varblock = "var s_s_c_user_id = '%s';\n" % self.user_id
        varblock += "var s_s_c_session_id = '%s';\n" % session_id
        varblock += "var s_s_c_captcha_field_id = 'keycaptcha_response_field';\n"
        varblock += "var s_s_c_submit_button_id = 'keycaptcha_response_button';\n"
        varblock += "var s_s_c_web_server_sign = '%s';\n" % sign1
        varblock += "var s_s_c_web_server_sign2 = '%s';\n" % sign2
        varblock += "document.s_s_c_debugmode=1;\n"
        fragment = tag(tag.script(varblock, type='text/javascript'))

        fragment.append(
            tag.script(type='text/javascript',
                       src='http://backs.keycaptcha.com/swfs/cap.js')
        )

        fragment.append(
            tag.input(type='hidden', id='keycaptcha_response_field',
                      name='keycaptcha_response_field')
        )

        fragment.append(
            tag.input(type='submit', id='keycaptcha_response_button',
                      name='keycaptcha_response_button')
        )

        req.session['captcha_key_session'] = session_id

        return None, fragment
Esempio n. 9
0
    def generate_captcha(self, req):
        add_script(req, 'https://www.google.com/recaptcha/api.js')

        return None, tag(
            tag.div(class_='g-recaptcha', data_sitekey=self.public_key),
            tag.input(type='submit', value=_("Submit"))
        )
Esempio n. 10
0
 def render_group(group):
     return tag.ul(
         tag.li(
             tag(tag.strong(elt[0].strip('/')), render_group(elt[1])
                 ) if isinstance(elt, tuple) else tag.
             a(wiki.format_page_name(omitprefix(elt)),
               href=formatter.href.wiki(elt))) for elt in group)
Esempio n. 11
0
    def render_ticket_action_control(self, req, ticket, action):
        id, grade = self._get_grade(req, action)

        review_options = self._get_review_options(action)
        actions = ConfigurableTicketWorkflow(self.env).actions

        selected_value = grade or review_options[0][0]

        label = actions[action]['label']
        control = tag([
            "as: ",
            tag.select([
                tag.option(option, selected=(option == selected_value or None))
                for option, status in review_options
            ],
                       name=id,
                       id=id)
        ])
        if grade:
            new_status = self._get_new_status(req, ticket, action,
                                              review_options)
            hint = "Next status will be '%s'" % new_status
        else:
            hint = "Next status will be one of " + \
                   ', '.join("'%s'" % status
                             for option, status in review_options)
        return label, control, hint
Esempio n. 12
0
    def _get_action_controls(self, req, tickets):
        action_controls = []
        ts = TicketSystem(self.env)
        tickets_by_action = {}
        for t in tickets:
            ticket = Ticket(self.env, t['id'])
            available_actions = ts.get_available_actions(req, ticket)
            for action in available_actions:
                tickets_by_action.setdefault(action, []).append(ticket)

        # Sort the allowed actions by the 'default' key.
        allowed_actions = set(tickets_by_action)
        workflow = ConfigurableTicketWorkflow(self.env)
        all_actions = sorted(((action['default'], name)
                              for name, action
                              in workflow.get_all_actions().iteritems()),
                             reverse=True)
        sorted_actions = [action[1] for action in all_actions
                                    if action[1] in allowed_actions]
        for action in sorted_actions:
            first_label = None
            hints = []
            widgets = []
            ticket = tickets_by_action[action][0]
            for controller in self._get_action_controllers(req, ticket,
                                                           action):
                label, widget, hint = controller.render_ticket_action_control(
                    req, ticket, action)
                if not first_label:
                    first_label = label
                widgets.append(widget)
                hints.append(hint)
            action_controls.append((action, first_label, tag(widgets), hints))
        return action_controls
Esempio n. 13
0
File: config.py Progetto: zxfly/trac
    def __get__(self, instance, owner):
        if instance is None:
            return self
        order = ListOption.__get__(self, instance, owner)
        components = []
        implementing_classes = []
        for impl in self.xtnpt.extensions(instance):
            implementing_classes.append(impl.__class__.__name__)
            if self.include_missing or impl.__class__.__name__ in order:
                components.append(impl)
        not_found = sorted(set(order) - set(implementing_classes))
        if not_found:
            raise ConfigurationError(
                tag_("Cannot find implementation(s) of the %(interface)s "
                     "interface named %(implementation)s. Please check "
                     "that the Component is enabled or update the option "
                     "%(option)s in trac.ini.",
                     interface=tag.code(self.xtnpt.interface.__name__),
                     implementation=tag(
                         (', ' if idx != 0 else None, tag.code(impl))
                         for idx, impl in enumerate(not_found)),
                     option=tag.code("[%s] %s" % (self.section, self.name))))

        def key(impl):
            name = impl.__class__.__name__
            if name in order:
                return 0, order.index(name)
            else:
                return 1, components.index(impl)
        return sorted(components, key=key)
Esempio n. 14
0
File: html.py Progetto: hanotch/trac
 def test_tracerror_with_tracerror_with_fragment(self):
     message = tag('Powered by ',
                   tag.a('Trac', href='http://trac.edgewall.org/'))
     rv = to_fragment(TracError(TracError(message)))
     self.assertEqual(Fragment, type(rv))
     self.assertEqual('Powered by <a href="http://trac.edgewall.org/">Trac'
                      '</a>', unicode(rv))
Esempio n. 15
0
File: html.py Progetto: hanotch/trac
 def test_tag(self):
     self.assertEqual(Markup('0<a>0</a> and <b>0</b> and <c></c>'
                             ' and <d class="a b" more_="[\'a\']"></d>'),
                      Markup(tag(0, tag.a(0, href=''), b' and ', tag.b(0.0),
                                 ' and ', tag.c(None), ' and ',
                                 tag.d('', class_=['a', '', 'b'],
                                       more__=[b'a']))))
    def post_process_request(self, req, template, data, content_type):
        if template is None or not req.session.authenticated:
            # Don't start the email verification procedure on anonymous users.
            return template, data, content_type

        email = req.session.get('email')
        # Only send verification if the user entered an email address.
        if self.verify_email and self.email_enabled is True and email and \
                email != req.session.get('email_verification_sent_to') and \
                'ACCTMGR_ADMIN' not in req.perm:
            req.session['email_verification_token'] = self._gen_token()
            req.session['email_verification_sent_to'] = email
            try:
                AccountManager(self.env)._notify(
                    'email_verification_requested',
                    req.authname,
                    req.session['email_verification_token']
                )
            except NotificationError, e:
                chrome.add_warning(req, _(
                    "Error raised while sending a change notification."
                ) + _("You should report that issue to a Trac admin."))
                self.log.error('Unable to send registration notification: %s',
                               exception_to_unicode(e, traceback=True))
            else:
                # TRANSLATOR: An email has been sent to <%(email)s>
                # with a token to ... (the link label for following message)
                link = tag.a(_("verify your new email address"),
                             href=req.href.verify_email())
                # TRANSLATOR: ... verify your new email address
                chrome.add_notice(req, tag_(
                    "An email has been sent to <%(email)s> with a token to "
                    "%(link)s.", email=tag(email), link=link))
Esempio n. 17
0
def linebreaks(value):
    """Converts newlines in strings into <p> and <br />s."""
    if not value:
        return ''
    value = re.sub(r'\r\n|\r|\n', '\n', value) # normalize newlines
    paras = re.split('\n{2,}', value)
    return tag(tag.p((line, tag.br) for line in para.splitlines())
               for para in paras)
Esempio n. 18
0
File: html.py Progetto: hanotch/trac
 def test_find_element_with_tag(self):
     frag = tag(tag.p('Paragraph with a ',
                tag.a('link', href='http://www.edgewall.org'),
                ' and some ', tag.strong('strong text')))
     self.assertIsNotNone(find_element(frag, tag='p'))
     self.assertIsNotNone(find_element(frag, tag='a'))
     self.assertIsNotNone(find_element(frag, tag='strong'))
     self.assertIsNone(find_element(frag, tag='input'))
     self.assertIsNone(find_element(frag, tag='textarea'))
Esempio n. 19
0
def create_graph_data(self, req, name=''):
    txt = req.args.get('text')
    if txt:
        actions, error_txt = get_workflow_actions_from_text(txt)
        if error_txt:
            t = error_txt
        else:
            t = "New custom workflow (not saved)"
        if not actions:
            # We should never end here...
            actions = get_workflow_config_by_type(self.config, 'default')
            t = "Custom workflow is broken. Showing default workflow"
    else:
        t = u""
        print(name)
        if name == 'default':
            actions = get_workflow_config_by_type(self.config, 'default')
        else:
            actions = get_workflow_config_by_type(self.config, name)

    states = list(set(
        [state for action in actions.itervalues()
         for state in action['oldstates']] + [action['newstate'] for action in
                                              actions.itervalues()]))

    action_labels = [action_info['label'] for action_name, action_info in
                     actions.items()]
    action_names = actions.keys()

    edges = []
    for name, action in actions.items():
        new_index = states.index(action['newstate'])
        name_index = action_names.index(name)
        for old_state in action['oldstates']:
            old_index = states.index(old_state)
            edges.append((old_index, new_index, name_index))

    args = {}
    width = args.get('width', 800)
    height = args.get('height', 600)
    graph = {'nodes': states, 'actions': action_labels, 'edges': edges,
             'width': width, 'height': height}
    graph_id = '%012x' % id(self)  # id(graph)

    scr_data = {'graph_%s' % graph_id: graph}

    res = tag(
        tag.p(t),
        tag.div('', class_='multiple-workflow-graph trac-noscript',
                id='trac-workflow-graph-%s' % graph_id,
                style="display:inline-block;width:%spx;height:%spx" %
                      (width, height)),
        tag.noscript(
            tag.div(_("Enable JavaScript to display the workflow graph."),
                    class_='system-message')))
    return res, scr_data, graph
Esempio n. 20
0
 def render_timeline_event(self, context, field, event):
     bp_resource, bp, bc = event[3]
     if bc: # A blog comment
         if field == 'url':
             return context.href.blog(bp.name) + '#comment-%d' % bc.number
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title), ' comment added')
         elif field == 'description':
             return format_to_oneliner(
                     self.env, context(resource=bp_resource), bc.comment)
     else: # A blog post
         if field == 'url':
             return context.href.blog(bp.name)
         elif field == 'title':
             return tag('Blog: ', tag.em(bp.title),
                     bp.version > 1 and ' edited' or ' created')
         elif field == 'description':
             return format_to_oneliner(
                     self.env, context(resource=bp_resource),
                     bp.version_comment)
Esempio n. 21
0
    def expand_macro(self, formatter, name, text, args):
        if not text:
            raw_actions = self.config.options('ticket-workflow')
        else:
            if args is None:
                text = '\n'.join(line.lstrip() for line in text.split(';'))
            if '[ticket-workflow]' not in text:
                text = '[ticket-workflow]\n' + text
            parser = RawConfigParser()
            try:
                parser.readfp(io.StringIO(text))
            except ParsingError as e:
                return system_message(_("Error parsing workflow."), unicode(e))
            raw_actions = list(parser.items('ticket-workflow'))
        actions = parse_workflow_config(raw_actions)
        states = list({
            state
            for action in actions.itervalues() for state in action['oldstates']
        } | {action['newstate']
             for action in actions.itervalues()})
        action_labels = [attrs['label'] for attrs in actions.values()]
        action_names = actions.keys()
        edges = []
        for name, action in actions.items():
            new_index = states.index(action['newstate'])
            name_index = action_names.index(name)
            for old_state in action['oldstates']:
                old_index = states.index(old_state)
                edges.append((old_index, new_index, name_index))

        args = args or {}
        width = args.get('width', 800)
        height = args.get('height', 600)
        graph = {
            'nodes': states,
            'actions': action_labels,
            'edges': edges,
            'width': width,
            'height': height
        }
        graph_id = '%012x' % id(graph)
        req = formatter.req
        add_script(req, 'common/js/excanvas.js', ie_if='IE')
        add_script(req, 'common/js/workflow_graph.js')
        add_script_data(req, {'graph_%s' % graph_id: graph})
        return tag(
            tag.div('',
                    class_='trac-workflow-graph trac-noscript',
                    id='trac-workflow-graph-%s' % graph_id,
                    style="display:inline-block;width:%spx;height:%spx" %
                    (width, height)),
            tag.noscript(
                tag.div(_("Enable JavaScript to display the workflow graph."),
                        class_='system-message')))
Esempio n. 22
0
 def _test_add_message_escapes_markup(self, msgtype, add_fn):
     req = MockRequest(self.env)
     add_fn(req, 'Message with an "&"')
     add_fn(req, Exception("Exception message with an &"))
     add_fn(req, tag("Message with text ", tag.b("& markup")))
     add_fn(req, Markup("Markup <strong>message</strong>."))
     messages = req.chrome[msgtype]
     self.assertIn('Message with an "&amp;"', messages)
     self.assertIn("Exception message with an &amp;", messages)
     self.assertIn("Message with text <b>&amp; markup</b>", messages)
     self.assertIn("Markup <strong>message</strong>.", messages)
Esempio n. 23
0
 def _format_link(self, formatter, ns, target, label):
     link, params, fragment = formatter.split_link(target)
     ids = link.split(':', 2)
     attachment = None
     if len(ids) == 3:
         known_realms = ResourceSystem(self.env).get_known_realms()
         # new-style attachment: TracLinks (filename:realm:id)
         if ids[1] in known_realms:
             attachment = Resource(ids[1], ids[2]).child(self.realm, ids[0])
         else:  # try old-style attachment: TracLinks (realm:id:filename)
             if ids[0] in known_realms:
                 attachment = Resource(ids[0],
                                       ids[1]).child(self.realm, ids[2])
     else:  # local attachment: TracLinks (filename)
         attachment = formatter.resource.child(self.realm, link)
     if attachment and 'ATTACHMENT_VIEW' in formatter.perm(attachment):
         try:
             Attachment(self.env, attachment)
         except ResourceNotFound:
             pass
         else:
             raw_href = get_resource_url(self.env,
                                         attachment,
                                         formatter.href,
                                         format='raw')
             title = get_resource_name(self.env, attachment)
             if ns.startswith('raw'):
                 return tag.a(label,
                              class_='attachment',
                              href=raw_href + params,
                              title=title)
             href = get_resource_url(self.env, attachment, formatter.href)
             return tag(
                 tag.a(label,
                       class_='attachment',
                       title=title,
                       href=href + params),
                 tag.a(u'\u200b',
                       class_='trac-rawlink',
                       href=raw_href + params,
                       title=_("Download")))
         # FIXME: should be either:
         #
         # model = Attachment(self.env, attachment)
         # if model.exists:
         #     ...
         #
         # or directly:
         #
         # if attachment.exists:
         #
         # (related to #4130)
     return tag.a(label, class_='missing attachment')
Esempio n. 24
0
    def expand_macro(self, formatter, name, content):
        args, kwargs = parse_args(content)
        format = kwargs.get('format', 'compact')
        glob = kwargs.get('glob', '*')
        order = kwargs.get('order')
        desc = as_bool(kwargs.get('desc', 0))

        rm = RepositoryManager(self.env)
        all_repos = dict(rdata for rdata in rm.get_all_repositories().items()
                         if fnmatchcase(rdata[0], glob))

        if format == 'table':
            repo = self._render_repository_index(formatter.context, all_repos,
                                                 order, desc)

            add_stylesheet(formatter.req, 'common/css/browser.css')
            wiki_format_messages = self.config['changeset'] \
                                       .getbool('wiki_format_messages')
            data = {'repo': repo, 'order': order, 'desc': 1 if desc else None,
                    'reponame': None, 'path': '/', 'stickyrev': None,
                    'wiki_format_messages': wiki_format_messages}
            return Chrome(self.env).render_fragment(formatter.context.req,
                                                    'repository_index.html',
                                                    data)

        def get_repository(reponame):
            try:
                return rm.get_repository(reponame)
            except TracError:
                return

        all_repos = [(reponame, get_repository(reponame))
                     for reponame in all_repos]
        all_repos = sorted(((reponame, repos) for reponame, repos in all_repos
                            if repos
                            and not as_bool(repos.params.get('hidden'))
                            and repos.is_viewable(formatter.perm)),
                           reverse=desc)

        def repolink(reponame, repos):
            label = reponame or _('(default)')
            return Markup(tag.a(label,
                          title=_('View repository %(repo)s', repo=label),
                          href=formatter.href.browser(repos.reponame or None)))

        if format == 'list':
            return tag.dl([
                tag(tag.dt(repolink(reponame, repos)),
                    tag.dd(repos.params.get('description')))
                for reponame, repos in all_repos])
        else: # compact
            return Markup(', ').join(repolink(reponame, repos)
                                     for reponame, repos in all_repos)
Esempio n. 25
0
    def post_process_request(self,
                             req,
                             template,
                             data,
                             content_type,
                             method=None):
        if req.path_info.startswith('/ticket/'):
            # In case of an invalid ticket, the data is invalid
            if not data:
                return template, data, content_type, method
            tkt = data['ticket']
            with self.env.db_query as db:
                links = CrashDumpTicketLinks(self.env, tkt, db=db)

                for change in data.get('changes', {}):
                    if not change.has_key('fields'):
                        continue
                    for field, field_data in change['fields'].iteritems():
                        if field in self.crashdump_link_fields:
                            if field_data['new'].strip():
                                new = set([
                                    CrashDumpSystem.get_crash_id(n)
                                    for n in field_data['new'].split(',')
                                ])
                            else:
                                new = set()
                            if field_data['old'].strip():
                                old = set([
                                    CrashDumpSystem.get_crash_id(n)
                                    for n in field_data['old'].split(',')
                                ])
                            else:
                                old = set()
                            add = new - old
                            sub = old - new
                            elms = tag()
                            if add:
                                elms.append(
                                    tag.em(u', '.join(
                                        [unicode(n) for n in sorted(add)])))
                                elms.append(u' added')
                            if add and sub:
                                elms.append(u'; ')
                            if sub:
                                elms.append(
                                    tag.em(u', '.join(
                                        [unicode(n) for n in sorted(sub)])))
                                elms.append(u' removed')
                            field_data['rendered'] = elms
                            links.crashes = new

        return template, data, content_type, method
 def render_action_control(self, req, ticket, action):
     first_label = None
     widgets = []
     hints = []
     for controller in self.controllers_for_action(req, ticket, action):
         label, widget, hint = controller.render_ticket_action_control(
             req, ticket, action)
         if first_label is None:
             first_label = label
         widgets.append(widget)
         hints.append(unicode(hint))
     hints = hints and '. '.join(hints) or ''
     return first_label, tag(*widgets), hints
Esempio n. 27
0
def get_existing_node(req, repos, path, rev):
    try:
        return repos.get_node(path, rev)
    except NoSuchNode as e:
        # TRANSLATOR: You can 'search' in the repository history... (link)
        search_a = tag.a(_("search"),
                         href=req.href.log(repos.reponame or None, path,
                                           rev=rev, mode='path_history'))
        raise ResourceNotFound(tag(
            tag.p(e, class_="message"),
            tag.p(tag_("You can %(search)s in the repository history to see "
                       "if that path existed but was later removed",
                       search=search_a))))
Esempio n. 28
0
 def _wiki_edit(self, req, stream):
     tags = ' '.join(self._page_tags(req))
     # TRANSLATOR: Label text for link to '/tags'.
     link = tag.a(_("view all tags"), href=req.href.tags())
     # TRANSLATOR: ... (view all tags)
     insert = tag(
         tag_("Tag under: (%(tags_link)s)", tags_link=link), tag.br(),
         tag.input(id='tags',
                   type='text',
                   name='tags',
                   size='50',
                   value=req.args.get('tags', tags)))
     insert = tag.div(tag.label(insert), class_='field')
     return stream | Transformer('//div[@id="changeinfo1"]').append(insert)
 def process_request(self, req):
     if req.path_info.startswith('/login') and req.authname == 'anonymous':
         try:
             referer = self._referer(req)
         except AttributeError:
             # Fallback for Trac 0.11 compatibility.
             referer = req.get_header('Referer')
         # Steer clear of requests going nowhere or loop to self.
         if referer is None or \
                 referer.startswith(str(req.abs_href()) + '/login'):
             referer = req.abs_href()
         data = {
             '_dgettext': dgettext,
             'login_opt_list': self.login_opt_list,
             'persistent_sessions':
                 AccountManager(self.env).persistent_sessions,
             'referer': referer,
             'registration_enabled': RegistrationModule(self.env).enabled,
             'reset_password_enabled':
                 AccountModule(self.env).reset_password_enabled
         }
         if req.method == 'POST':
             self.log.debug("LoginModule.process_request: 'user_locked' "
                            "= %s", req.args.get('user_locked'))
             if not req.args.get('user_locked'):
                 # TRANSLATOR: Intentionally obfuscated login error
                 data['login_error'] = _("Invalid username or password")
             else:
                 f_user = req.args.get('username')
                 release_time = AccountGuard(self.env
                                             ).pretty_release_time(req,
                                                                   f_user)
                 if release_time is not None:
                     data['login_error'] = \
                         _("Account locked, please try again after % "
                           "(release_time)s", release_time=release_time)
                 else:
                     data['login_error'] = _("Account locked")
         return 'login.html', data, None
     else:
         n_plural = req.args.get('failed_logins')
         if n_plural > 0:
             add_warning(req, tag(ngettext(
                 "Login after %(attempts)s failed attempt",
                 "Login after %(attempts)s failed attempts",
                 n_plural, attempts=n_plural
             )))
     return auth.LoginModule.process_request(self, req)
Esempio n. 30
0
 def _render_link(self, context, name, label, extra=''):
     if not (name or extra):
         return tag()
     try:
         milestone = Milestone(self.env, name)
     except ResourceNotFound:
         milestone = None
     # Note: the above should really not be needed, `Milestone.exists`
     # should simply be false if the milestone doesn't exist in the db
     # (related to #4130)
     href = context.href.milestone(name)
     exists = milestone and milestone.exists
     if exists:
         if 'MILESTONE_VIEW' in context.perm(milestone.resource):
             title = None
             if hasattr(context, 'req'):
                 if milestone.is_completed:
                     title = _("Completed %(duration)s ago (%(date)s)",
                               duration=pretty_timedelta(
                                   milestone.completed),
                               date=user_time(context.req, format_datetime,
                                              milestone.completed))
                 elif milestone.is_late:
                     title = _("%(duration)s late (%(date)s)",
                               duration=pretty_timedelta(milestone.due),
                               date=user_time(context.req, format_datetime,
                                              milestone.due))
                 elif milestone.due:
                     title = _("Due in %(duration)s (%(date)s)",
                               duration=pretty_timedelta(milestone.due),
                               date=user_time(context.req, format_datetime,
                                              milestone.due))
                 else:
                     title = _("No date set")
             closed = 'closed ' if milestone.is_completed else ''
             return tag.a(label,
                          class_='%smilestone' % closed,
                          href=href + extra,
                          title=title)
     elif 'MILESTONE_CREATE' in context.perm(self.realm, name):
         return tag.a(label,
                      class_='missing milestone',
                      href=href + extra,
                      rel='nofollow')
     return tag.a(label, class_=classes('milestone', missing=not exists))
Esempio n. 31
0
 def _post_process_request_wiki_edit(self, req):
     tags = ' '.join(self._page_tags(req))
     # TRANSLATOR: Label text for link to '/tags'.
     link = tag.a(_("view all tags"), href=req.href.tags())
     # TRANSLATOR: ... (view all tags)
     insert = tag(
         tag_("Tag under: (%(tags_link)s)", tags_link=link), tag.br(),
         tag.input(id='tags',
                   type='text',
                   name='tags',
                   size='50',
                   value=req.args.get('tags', tags)))
     insert = tag.div(tag.label(insert), class_='field')
     filter_lst = []
     # xpath = //div[@id="changeinfo1"]
     xform = JTransformer('div#changeinfo1')
     filter_lst.append(xform.append(Markup(insert)))
     self._add_jtransform(req, filter_lst)
Esempio n. 32
0
 def _format_browser_link(self, formatter, ns, path, label):
     path, query, fragment = formatter.split_link(path)
     rev = marks = None
     match = self.PATH_LINK_RE.match(path)
     if match:
         path, rev, marks = match.groups()
     href = formatter.href
     src_href = href.browser(path, rev=rev, marks=marks) + query + fragment
     node, raw_href, title = self._get_link_info(path, rev, formatter.href,
                                                 formatter.perm)
     if not node:
         return tag.a(label, class_='missing source')
     link = tag.a(label, class_='source', href=src_href)
     if raw_href:
         link = tag(link, tag.a(u'\u200b', href=raw_href + fragment,
                                title=title,
                                class_='trac-rawlink' if node.isfile
                                       else 'trac-ziplink'))
     return link
Esempio n. 33
0
 def render_timeline_event(self, context, field, event):
     wiki_page, comment = event[3]
     if field == 'url':
         return context.href.wiki(wiki_page.id, version=wiki_page.version)
     elif field == 'title':
         name = tag.em(get_resource_name(self.env, wiki_page))
         if wiki_page.version > 1:
             return tag_("%(page)s edited", page=name)
         else:
             return tag_("%(page)s created", page=name)
     elif field == 'description':
         markup = format_to(self.env, None,
                            context.child(resource=wiki_page), comment)
         if wiki_page.version > 1:
             diff_href = context.href.wiki(
                 wiki_page.id, version=wiki_page.version, action='diff')
             markup = tag(markup,
                          " (", tag.a(_("diff"), href=diff_href), ")")
         return markup
Esempio n. 34
0
    def render_ticket_action_control(self, req, ticket, action):
        id, selected = self._get_selected(req, action)

        review_options = self._get_review_options(action)
        actions = ConfigurableTicketWorkflow(self.env).actions

        label = actions[action]['label']
        control = tag(["as: ",
                       tag.select([
                           tag.option(option,
                                      selected=(option == selected or None))
                           for option in review_options],
                           name=id, id=id)])
        if selected:
            new_status = self._get_new_status(req, action, review_options)
            hint = "Next status will be '%s'" % new_status
        else:
            hint = "Next status will be one of " + \
                   ', '.join("'%s'" % st for st in review_options.itervalues())
        return label, control, hint
Esempio n. 35
0
    def _link_tickets(self, req, tickets):
        if tickets is None:
            return None

        if not isinstance(tickets, str) and not isinstance(tickets, unicode):
            self.log.debug('_link_tickets %s invalid type (%s)' %
                           (tickets, type(tickets)))
            return None

        if not tickets:
            return None

        items = []
        for i, word in enumerate(re.split(r'([;,\s]+)', tickets)):
            if i % 2:
                items.append(word)
            elif word:
                ticketid = word
                word = '#%s' % word

                try:
                    ticket = Ticket(self.env, ticketid)
                    if 'TICKET_VIEW' in req.perm(ticket.resource):
                        word = \
                            tag.a(
                                '#%s' % ticket.id,
                                class_=ticket['status'],
                                href=req.href.ticket(int(ticket.id)),
                                title=shorten_line(ticket['summary'])
                            )
                except ResourceNotFound:
                    pass

                items.append(word)

        if items:
            return tag(items)
        else:
            return None
Esempio n. 36
0
    def _get_action_controls(self, req, ticket_data):
        tickets = [Ticket(self.env, t['id']) for t in ticket_data]
        action_weights = {}
        action_tickets = {}
        for t in tickets:
            for ctrl in TicketSystem(self.env).action_controllers:
                for weight, action in ctrl.get_ticket_actions(req, t) or []:
                    if action in action_weights:
                        action_weights[action] = max(action_weights[action],
                                                     weight)
                        action_tickets[action].append(t)
                    else:
                        action_weights[action] = weight
                        action_tickets[action] = [t]

        sorted_actions = [
            a for a, w in sorted(action_weights.iteritems(),
                                 key=lambda item: (item[1], item[0]),
                                 reverse=True)
        ]

        action_controls = []
        for action in sorted_actions:
            first_label = None
            hints = []
            widgets = []
            ticket = action_tickets[action][0]
            for controller in self._get_action_controllers(
                    req, ticket, action):
                label, widget, hint = controller.render_ticket_action_control(
                    req, ticket, action)
                if not first_label:
                    first_label = label
                widgets.append(widget)
                hints.append(hint)
            action_controls.append((action, first_label, tag(widgets), hints))
        return action_controls
Esempio n. 37
0
    def _provider_failure(self, exc, req, ep, current_filters, all_filters):
        """Raise a TracError exception explaining the failure of a provider.

        At the same time, the message will contain a link to the timeline
        without the filters corresponding to the guilty event provider `ep`.
        """
        self.log.error("Timeline event provider failed: %s",
                       exception_to_unicode(exc, traceback=True))

        ep_kinds = {f[0]: f[1] for f in ep.get_timeline_filters(req) or []}
        ep_filters = set(ep_kinds.keys())
        current_filters = set(current_filters)
        other_filters = set(current_filters) - ep_filters
        if not other_filters:
            other_filters = set(all_filters) - ep_filters
        args = [(a, req.args.get(a))
                for a in ('from', 'format', 'max', 'daysback')]
        href = req.href.timeline(args + [(f, 'on') for f in other_filters])
        # TRANSLATOR: ...want to see the 'other kinds of events' from... (link)
        other_events = tag.a(_('other kinds of events'), href=href)
        raise TracError(
            tag(
                tag.p(tag_(
                    "Event provider %(name)s failed for filters "
                    "%(kinds)s: ",
                    name=tag.code(ep.__class__.__name__),
                    kinds=', '.join('"%s"' % ep_kinds[f]
                                    for f in current_filters & ep_filters)),
                      tag.strong(exception_to_unicode(exc)),
                      class_='message'),
                tag.p(
                    tag_(
                        "You may want to see the %(other_events)s from the "
                        "Timeline or notify your Trac administrator about the "
                        "error (detailed information was written to the log).",
                        other_events=other_events))))
Esempio n. 38
0
    def filter_stream(self, req, method, filename, stream, data):
        if req.path_info.startswith('/register') and (
            req.method == 'GET' or
            'registration_error' in data or
                'captcha_error' in req.session):
            if not (self.private_key or self.private_key):
                return stream
            captcha_opts = tag.script("""\
var RecaptchaOptions = {
  theme: "%s",
  lang: "%s"
}""" % (self.theme, self.lang), type='text/javascript')
            captcha_js = captcha.displayhtml(
                self.public_key, use_ssl=req.scheme == 'https',
                error='reCAPTCHA incorrect. Please try again.',
                version=2
            ) + captcha.load_script(version=2)
            # First Fieldset of the registration form XPath match
            xpath_match = '//form[@id="acctmgr_registerform"]/fieldset[1]'
            return stream | Transformer(xpath_match). \
                append(captcha_opts + tag(Markup(captcha_js)))
        # Admin Configuration
        elif req.path_info.startswith('/admin/accounts/config'):
            api_html = tag.div(
                tag.label("Public Key:", for_="recaptcha_public_key") +
                tag.input(class_="textwidget", name="recaptcha_public_key",
                          value=self.public_key, size=40)
            ) + tag.div(
                tag.label("Private Key:", for_="recaptcha_private_key") +
                tag.input(class_="textwidget", name="recaptcha_private_key",
                          value=self.private_key, size=40)
            )
            if not (self.private_key or self.public_key):
                api_html = tag.div(
                    tag.a("Generate a reCAPTCHA API key for this Trac "
                          "instance domain.", target="_blank",
                          href="http://recaptcha.net/api/getkey?domain=%s&"
                          "app=TracRecaptchaRegister" %
                          req.environ.get('SERVER_NAME')
                          )
                ) + tag.br() + api_html

            theme_html = tag.div(
                tag.label("reCPATCHA theme:", for_='recaptcha_theme') +
                tag.select(
                    tag.option("Black Glass",
                               value="blackglass",
                               selected=self.theme == 'blackglass' or None) +
                    tag.option("Clean",
                               value="clean",
                               selected=self.theme == 'clean' or None) +
                    tag.option("Red",
                               value="red",
                               selected=self.theme == 'red' or None) +
                    tag.option("White",
                               value="white",
                               selected=self.theme == 'white' or None),
                    name='recaptcha_theme'
                )
            )

            language_html = tag.div(
                tag.label("reCAPTCHA language:", for_='recaptcha_lang') +
                tag.select(
                    tag.option("Dutch",
                               value="nl",
                               selected=self.lang == 'nl' or None) +
                    tag.option("English",
                               value="en",
                               selected=self.lang == 'en' or None) +
                    tag.option("French",
                               selected=self.lang == 'fr' or None) +
                    tag.option("German",
                               value="de",
                               selected=self.lang == 'de' or None) +
                    tag.option("Portuguese",
                               value="pt",
                               selected=self.lang == 'pt' or None) +
                    tag.option("Russian",
                               value="ru",
                               selected=self.lang == 'ru' or None) +
                    tag.option("Spanish",
                               value="es",
                               selected=self.lang == 'es' or None) +
                    tag.option("Turkish",
                               value="tr",
                               selected=self.lang == 'tr' or None),
                    name='recaptcha_lang'))

            # First fieldset of the Account Manager config form
            xpath_match = '//form[@id="cfg_wiz"]/fieldset[1]'

            return stream | Transformer(xpath_match). \
                before(tag.fieldset(tag.legend("reCAPTCHA") + api_html +
                                    tag.br() + theme_html + language_html))
        return stream
Esempio n. 39
0
 def render_groups(groups):
     return tag.ul(
         [tag.li(isinstance(elt, tuple) and 
                 tag(tag.strong(elt[0]), render_groups(elt[1])) or
                 render_one(elt, pagelangs.get(elt)))
          for elt in groups])
 def expand_macro(self, formatter, name, content):
     env = formatter.env
     req = formatter.req
     if not content:
         args = []
         kw = {}
     else:
         args, kw = parse_args(content)
     if name == 'ProjectStats':
         if 'wiki' in kw.keys():
             prefix = 'prefix' in kw.keys() and kw['prefix'] or None
             wiki = WikiSystem(env)
             if kw['wiki'] == 'count' or 'count' in args:
                 return tag(len(list(wiki.get_pages(prefix))))
     elif name == 'UserQuery':
         msg_no_perm = tag.p(tag_("(required %(perm)s missing)",
                                  perm=tag.strong('USER_VIEW')),
                             class_='hint')
         if 'perm' in kw.keys():
             perm_sys = PermissionSystem(self.env)
             users = perm_sys.get_users_with_permission(kw['perm'].upper())
         else:
             acct_mgr = AccountManager(env)
             users = list(set(acct_mgr.get_users()))
         if 'locked' in kw.keys() or 'locked' in args:
             guard = AccountGuard(env)
             locked = []
             for user in users:
                 if guard.user_locked(user):
                     locked.append(user)
             if kw.get('locked', 'True').lower() in ('true', 'yes', '1'):
                 users = locked
             else:
                 users = list(set(users) - set(locked))
         elif 'visit' in kw.keys() or 'visit' in args:
             if 'USER_VIEW' not in req.perm:
                 return msg_no_perm
             cols = []
             data = {'accounts': fetch_user_data(env, req), 'cls': 'wiki'}
             for col in ('email', 'name'):
                 if col in args:
                     cols.append(col)
             data['cols'] = cols
             return Chrome(env).render_template(
                 req, 'user_table.html', data, 'text/html', True)
         if kw.get('format') == 'count' or 'count' in args:
             return tag(len(users))
         if 'USER_VIEW' not in req.perm:
             return msg_no_perm
         if 'email' in args or 'name' in args:
             # Replace username with full name, add email if available.
             for username, name, email in self.env.get_known_users():
                 if username in users:
                     if 'name' not in args or name is None:
                         name = username
                     if 'email' in args and email is not None:
                         email = ''.join(['<', email, '>'])
                         name = ' '.join([name, email])
                     if not username == name:
                         users.pop(users.index(username))
                         users.append(name)
         if not users and 'nomatch' in kw.keys():
             return format_to_oneliner(env, formatter.context,
                                       kw['nomatch'])
         users = sorted(users)
         if kw.get('format') == 'list':
             return tag.ul([tag.li(Chrome(env).format_author(req, user))
                            for user in users])
         else:
             # Default output format: comma-separated list.
             return tag(', '.join([Chrome(env).format_author(req, user)
                                   for user in users]))