Beispiel #1
0
    def _do_rename(self, req, page):
        if page.readonly:
            req.perm(page.resource).require('WIKI_ADMIN')
        else:
            req.perm(page.resource).require('WIKI_RENAME')
        if 'cancel' in req.args:
            req.redirect(get_resource_url(self.env, page.resource, req.href))
        old_name, old_version = page.name, page.version
        new_name = req.args.get('new_name', '').rstrip('/')
        redirect = req.args.get('redirect')
        # verify input parameters
        warn = None
        if not new_name:
            warn = _('A new name is mandatory for a rename.')
        elif new_name == old_name:
            warn = _('The new name must be different from the old name.')
        elif WikiPage(self.env, new_name).exists:
            warn = _('The page %(name)s already exists.', name=new_name)
        if warn:
            add_warning(req, warn)
            return self._render_confirm_rename(req, page, new_name)

        @self.env.with_transaction()
        def do_rename(db):
            page.rename(new_name)
            if redirect:
                redirection = WikiPage(self.env, old_name, db=db)
                redirection.text = _('See [wiki:"%(name)s"].', name=new_name)
                author = get_reporter_id(req)
                comment = u'[wiki:"%s@%d" %s] \u2192 [wiki:"%s"].' % (
                          new_name, old_version, old_name, new_name)
                redirection.save(author, comment, req.remote_addr)
        
        req.redirect(req.href.wiki(redirect and old_name or new_name))
Beispiel #2
0
    def _do_delete(self, req, milestone):
        req.perm(milestone.resource).require('MILESTONE_DELETE')

        retarget_to = req.args.get('target') or None
        # Don't translate ticket comment (comment:40:ticket:5658)
        retargeted_tickets = \
            milestone.move_tickets(retarget_to, req.authname,
                "Ticket retargeted after milestone deleted")
        milestone.delete(author=req.authname)
        add_notice(req, _('The milestone "%(name)s" has been deleted.',
                          name=milestone.name))
        if retargeted_tickets:
            add_notice(req, _('The tickets associated with milestone '
                              '"%(name)s" have been retargeted to milestone '
                              '"%(retarget)s".', name=milestone.name,
                              retarget=retarget_to))
            new_values = {'milestone': retarget_to}
            comment = _("Tickets retargeted after milestone deleted")
            tn = BatchTicketNotifyEmail(self.env)
            try:
                tn.notify(retargeted_tickets, new_values, comment, None,
                          req.authname)
            except Exception, e:
                self.log.error("Failure sending notification on ticket batch "
                               "change: %s", exception_to_unicode(e))
                add_warning(req, tag_("The changes have been saved, but an "
                                      "error occurred while sending "
                                      "notifications: %(message)s",
                                      message=to_unicode(e)))
 def process_request(self, req):
     if not req.session.authenticated:
         chrome.add_warning(req, tag_(
             "Please log in to finish email verification procedure."))
         req.redirect(req.href.login())
     if 'email_verification_token' not in req.session:
         chrome.add_notice(req, _("Your email is already verified."))
     elif req.method == 'POST' and 'resend' in req.args:
         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 verification notification: %s',
                            exception_to_unicode(e, traceback=True))
         else:
             chrome.add_notice(req, _("A notification email has been "
                                      "resent to <%s>."),
                               req.session.get('email'))
    def render_admin_panel(self, req, cat, page, path_info):
        req.perm.require('TRAC_ADMIN')

        status, message = init_admin(self.gitosis_user, self.gitosis_server, self.admrepo, self.env.path)
        data = {}
        if status != 0:
          add_warning(req, _('Error while cloning gitosis-admin repository. Please check your settings and/or passphrase free connection to this repository for the user running trac (in most cases, the web server user)'))
          message = 'return code: '+str(status)+'\nmessage:\n'+message
          if message:
            add_warning(req, _(message))
        repo = replace(os.path.basename(self.config.get('trac', 'repository_dir')), '.git', '')
        if req.method == 'POST':
            config = {}
            self.log.debug('description: '+req.args.get('description'))
            for option in ('daemon', 'gitweb', 'description', 'owner'):
                 config[option] = req.args.get(option)
            self.set_config(repo, config)
            req.redirect(req.href.admin(cat, page))
        repo = replace(os.path.basename(self.config.get('trac', 'repository_dir')), '.git', '')
        if repo != '':
            data = self.get_config(repo)
        self.log.debug('data: %s', str(data))
        if not data:
            data = {}
        for option in ('daemon', 'gitweb', 'description', 'owner'):
            if option not in data:
                data[option] = ''
        data['gitweb'] = data['gitweb'] in _TRUE_VALUES
        data['daemon'] = data['daemon'] in _TRUE_VALUES
        return 'admin_tracgitosis_repo.html', {'repo': data}
Beispiel #5
0
    def _process_changes(self, req, protos, scm_type):
        scm_protos = dav_protos = set([])

        allowed_scm_schemes = protos.allowed_protocols(scm_type)
        allowed_dav_schemes = protos.allowed_protocols('dav')

        if 'scm_proto' in req.args:
            scm_protos = set(self._to_list(req.args['scm_proto']))
        if 'dav_proto' in req.args:
            dav_protos = set(self._to_list(req.args['dav_proto']))

        if not self._validate(scm_protos, dav_protos):
            msg = 'Changes not stored, make sure that at least one protocol for each ' \
                  'section is selected. If you want to disable any section, configure ' \
                  'the appropriate permissions in the "Groups" page'
            add_warning(req, msg)
            return

        try:
            # Change scm protocols
            protos.disallow_protocols(allowed_scm_schemes - scm_protos, scm_type)
            protos.allow_protocols(scm_protos - allowed_scm_schemes, scm_type)

            # Change dav protocols
            protos.disallow_protocols(allowed_dav_schemes - dav_protos, 'dav')
            protos.allow_protocols(dav_protos - allowed_dav_schemes, 'dav')
        except:
            raise TracError("Server error. Try again later.")

        add_notice(req, "Changes saved")
Beispiel #6
0
    def render_admin_panel(self, req, cat, page, version):
        self.log.debug("cat: %s page: %s", cat, page)
        req.perm.require('TRAC_ADMIN')

        options = (
            'api_base_url',
            'api_token',
            'room_id',
            'only_owner_changed',
            'notify_symbol',
            'api_token_field_name')

        self.log.debug("method: %s", req.method)
        if req.method == 'POST':
            for option in options:
                self.config.set(SECTION_NAME, option, req.args.get(option))

            try:
                self.config.save()
                self.log.debug('config saved.')
                add_notice(req, 'Your changes have been saved.')
            except Exception, e:
                self.log.error("Error writing to trac.ini: %s", exception_to_unicode(e))
                add_warning(req, 'Error writing to trac.ini.')

            req.redirect(req.href.admin(cat, page))
Beispiel #7
0
 def _do_account(self, req):
     assert(req.authname and req.authname != 'anonymous')
     action = req.args.get('action')
     delete_enabled = self.acctmgr.supports('delete_user') and \
                          self.acctmgr.allow_delete_account
     data = {'delete_enabled': delete_enabled,
             'delete_msg_confirm': _(
                 "Are you sure you want to delete your account?"),
            }
     force_change_password = req.session.get('force_change_passwd', False)
     if req.method == 'POST':
         if action == 'save':
             data.update(self._do_change_password(req))
             if force_change_password:
                 del(req.session['force_change_passwd'])
                 req.session.save()
                 chrome.add_notice(req, Markup(tag.span(tag_(
                     "Thank you for taking the time to update your password."
                 ))))
                 force_change_password = False
         elif action == 'delete' and delete_enabled:
             data.update(self._do_delete(req))
         else:
             data.update({'error': 'Invalid action'})
     if force_change_password:
         chrome.add_warning(req, Markup(tag.span(_(
             "You are required to change password because of a recent "
             "password change request. "),
             tag.b(_("Please change your password now.")))))
     return data
 def pre_process_request(self, req, handler):
     if not req.authname or req.authname == 'anonymous':
         # Permissions for anonymous users remain unchanged.
         return handler
     elif req.path_info == '/prefs' and \
                     req.method == 'POST' and \
                     'restore' not in req.args and \
                     req.get_header(
                         'X-Requested-With') != 'XMLHttpRequest':
         try:
             AccountManager(self.env).validate_account(req)
             # Check passed without error: New email address seems good.
         except RegistrationError, e:
             # Always warn about issues.
             chrome.add_warning(req, e)
             # Look, if the issue existed before.
             attributes = get_user_attribute(self.env, req.authname,
                                             attribute='email')
             email = req.authname in attributes and \
                     attributes[req.authname][1].get('email') or None
             new_email = req.args.get('email', '').strip()
             if (email or new_email) and email != new_email:
                 # Attempt to change email to an empty or invalid
                 # address detected, resetting to previously stored value.
                 req.redirect(req.href.prefs(None))
Beispiel #9
0
    def _render_source(self, context, stream, annotations, marks=None):
        from trac.web.chrome import add_warning
        annotators, labels, titles = {}, {}, {}
        for annotator in self.annotators:
            atype, alabel, atitle = annotator.get_annotation_type()
            if atype in annotations:
                labels[atype] = alabel
                titles[atype] = atitle
                annotators[atype] = annotator
        annotations = [a for a in annotations if a in annotators]

        if isinstance(stream, list):
            stream = HTMLParser(StringIO(u'\n'.join(stream)))
        elif isinstance(stream, unicode):
            text = stream
            def linesplitter():
                for line in text.splitlines(True):
                    yield TEXT, line, (None, -1, -1)
            stream = linesplitter()

        annotator_datas = []
        for a in annotations:
            annotator = annotators[a]
            try:
                data = (annotator, annotator.get_annotation_data(context))
            except TracError, e:
                self.log.warning("Can't use annotator '%s': %s", a, e.message)
                add_warning(context.req, tag.strong(
                    tag_("Can't use %(annotator)s annotator: %(error)s",
                         annotator=tag.em(a), error=tag.pre(e.message))))
                data = (None, None)
            annotator_datas.append(data)
Beispiel #10
0
    def commit(self, req):
        """Perform the operation for all processed rows. Return a list of new 
        or changed tickets"""
        tickets = []

        if not self.do_preview:
            for fields in self.rows:
                ticket = self._get_ticket_from_id_in_csv(req, fields)
                if ticket == None:
                    continue
                ticket_type = self._get_type_for_ticket(fields)
                if not self._may_create_ticket(req.perm, ticket_type):
                    add_warning(req, _("No permission to create a %s.") % ticket_type)
                    continue

                if not self.force:
                    csv_summary = fields[Key.SUMMARY]
                    db_summary = ticket[Key.SUMMARY]
                    if csv_summary != db_summary:
                        msg = _("Ticket %d has a different summary: '%s' (CSV) - '%s' (DB)")
                        add_warning(req, msg % (ticket.id, repr(csv_summary), repr(db_summary)))
                        continue
                tickets.append(ticket)
                ticket.delete()
        return tickets
    def render_preference_panel(self, req, panel):
        """ Renders preference panel and handles image change on POST
        """

        if req.authname == 'anonymous':
            raise TracError("User is not authenticated", "No access")

        userstore = get_userstore()
        user = userstore.getUser(req.authname)

        if req.method == 'POST':
            if 'removeicon' in req.args:
                user.icon = None
                userstore.updateUser(user)
            elif 'icon' in req.args:
                user.createIcon(req.args['icon'])

                if user.icon:
                    userstore.updateUser(user)

        data = {'user':user, 'base_path':req.base_path}
        if 'limitexceeded' in req.args:
            add_warning(req, 'Picture you tried to upload was too big. Try a smaller one.')

        return 'multiproject_user_prefs_image.html', data
    def render_preference_panel(self, req, panel):
        """ Renders preference panel and handles information change on POST
        """
        if req.authname == 'anonymous':
            raise TracError("User is not authenticated", "No access")

        data = {}
        key_store = CQDESshKeyStore.instance()
        user = get_userstore().getUser(req.authname)

        if req.method == 'POST':
            ssh_key = req.args.get('ssh_key')
            delete_key = req.args.get('deletelist')

            if ssh_key:
                user = self._do_save(req, user)
            elif delete_key:
                user = self._do_deletes(req, user)
            else:
                add_warning(req, _('Please provide data'))

        keys = key_store.get_ssh_keys_by_user_id(user.id)
        data['keys'] = keys if keys else None

        # This is to prevent adding of more than one ssh password.
        # Remove this if we support more in the future.
        if keys:
            data['hide_add_dialog'] = False

        data['domain'] = conf.domain_name
        data['user'] = user

        return 'multiproject_user_prefs_ssh_keys.html', data
Beispiel #13
0
 def setkeys(self, req, keys):
     if req.authname == 'anonymous':
         raise TracError('cannot set ssh keys for anonymous users')
     keys = set(keys)
     if len(keys) > 0x100:
         add_warning(req, 'We only support using your first 256 ssh keys.')
     return self._setkeys(req.authname, keys)
Beispiel #14
0
    def get_ticket_changes(self, req, ticket, action):
        # WARNING: Directly modifying the ticket in this method breaks the
        # intent of this method.  But it does accomplish the desired goal.
        if not 'preview' in req.args:
            id = 'action_%s_xref' % action
            ticketnum = req.args.get(id).strip('#')

            try:
                xticket = model.Ticket(self.env, ticketnum)
            except ValueError:
                req.args['preview'] = True
                add_warning(req, 'The cross-referenced ticket number "%s" was not a number' % ticketnum)
                return {}
            except ResourceNotFound, e:
                #put in preview mode to prevent ticket being saved
                req.args['preview'] = True
                add_warning(req, "Unable to cross-reference Ticket #%s (%s)." % (ticketnum, e.message))
                return {}

            oldcomment = req.args.get('comment')
            actions = self.get_configurable_workflow().actions
            format_string = actions[action].get('xref_local',
                'Ticket %s was marked as related to this ticket')
            # Add a comment to this ticket to indicate that the "remote" ticket is
            # related to it.  (But only if <action>.xref_local was set in the
            # config.)
            if format_string:
                comment = format_string % ('#%s' % ticketnum)
                req.args['comment'] = "%s%s%s" % \
                    (comment, oldcomment and "[[BR]]" or "", oldcomment or "")
def post_new_artifact(request, dbp, obj, resource):
    require_permission(request.req, resource, dbp.env, operation="CREATE")

    assert(obj is Instance or isinstance(obj, Entity)) # otherwise, we're trying to instantiate something that is not an artifact

    spec_name = request.req.args['spec']
    if spec_name:
        try:
            dbp.load_spec(spec_name)
            spec = dbp.pool.get_item(spec_name)
        except ValueError:
            add_warning(request.req, "Spec '%s' not found, assumed an empty spec instead." % spec_name)
            spec = Instance
    else:
        spec = Instance

    values, str_attr = _group_artifact_values(request.req)
    brand_new_inst = spec(str_attr=str_attr, values=values)

    dbp.pool.add(brand_new_inst)
    dbp.save(get_reporter_id(request.req), 'comment', request.req.remote_addr)

    if request.get_format() == 'page':
        add_notice(request.req, 'Your changes have been saved.')
        url = request.req.href.customartifacts('artifact/%d' % (brand_new_inst.get_id(),), action='view', format=request.get_format())
        request.req.redirect(url)
    else:
        import json
        url = request.req.href.customartifacts('artifact/%d' % (brand_new_inst.get_id(),), action='view')
        msg = json.dumps([{'result': 'success', 'resource_id': brand_new_inst.get_id(), 'resource_url': url}])
        request.req.send_response(200)
        request.req.send_header('Content-Type', 'application/json')
        request.req.send_header('Content-Length', len(msg))
        request.req.end_headers()
        request.req.write(msg)
    def _do_change_password(self, req):
        username = req.authname

        old_password = req.args.get('old_password')
        if not self.acctmgr.check_password(username, old_password):
            if old_password:
                add_warning(req, _("Old password is incorrect."))
            else:
                add_warning(req, _("Old password cannot be empty."))
            return
        password = req.args.get('password')
        if not password:
            add_warning(req, _("Password cannot be empty."))
        elif password != req.args.get('password_confirm'):
            add_warning(req, _("The passwords must match."))
        elif password == old_password:
            add_warning(req, _("Password must not match old password."))
        else:
            _set_password(self.env, req, username, password, old_password)
            if req.session.get('password') is not None:
                # Fetch all session_attributes in case new user password is in
                # SessionStore, preventing overwrite by session.save().
                req.session.get_session(req.authname, authenticated=True)
            add_notice(req, _("Password updated successfully."))
            return True
Beispiel #17
0
 def process_request(self, req): 
     if req.path_info == '/traccron/runtask':
         self._runtask(req)
     else:
         self.env.log.warn("Trac Cron Plugin was unable to handle %s" % req.path_info)
         add_warning(req, "The request was not handled by trac cron plugin")
         req.redirect(req.href.admin('traccron','cron_admin'))
Beispiel #18
0
 def process_request(self, req):
     if not req.session.authenticated:
         chrome.add_warning(req, Markup(tag.span(tag_(
             "Please log in to finish email verification procedure.")))
         )
         req.redirect(req.href.login())
     if 'email_verification_token' not in req.session:
         chrome.add_notice(req, _("Your email is already verified."))
     elif req.method == 'POST' and 'resend' in req.args:
         AccountManager(self.env)._notify(
             'email_verification_requested', 
             req.authname, 
             req.session['email_verification_token']
         )
         chrome.add_notice(req,
                 _("A notification email has been resent to <%s>."),
                 req.session.get('email')
         )
     elif 'verify' in req.args:
         # allow via POST or GET (the latter for email links)
         if req.args['token'] == req.session['email_verification_token']:
             del req.session['email_verification_token']
             chrome.add_notice(
                 req, _("Thank you for verifying your email address.")
             )
             req.redirect(req.href.prefs())
         else:
             chrome.add_warning(req, _("Invalid verification token"))
     data = {'_dgettext': dgettext}
     if 'token' in req.args:
         data['token'] = req.args['token']
     if 'email_verification_token' not in req.session:
         data['button_state'] = { 'disabled': 'disabled' }
     return 'verify_email.html', data, None
Beispiel #19
0
 def _reject_oauth(self, req, exc, reason=None):
     self.log.warn("An OAuth authorization attempt was rejected due to an "
                   "exception: %s\n%s", exc, traceback.format_exc())
     if reason is None:
         reason = _("Invalid request. Please try to login again.")
     add_warning(req, reason)
     self._redirect_back(req)
    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))
Beispiel #21
0
    def _add_organization(self, req, group_store):
        req.perm.require("PERMISSION_GRANT")

        group_name = req.args.get("group")
        organization = req.args.get("organization")

        try:
            group_store.add_organization_to_group(organization, group_name)
            add_notice(
                req,
                _(
                    "Organization %(organization)s added to group %(group)s",
                    group=group_name,
                    organization=organization,
                ),
            )
        except ValueError:
            add_warning(
                req,
                _(
                    "Organization %(organization)s already exists in group %(group)s",
                    group=group_name,
                    organization=organization,
                ),
            )
    def pre_process_request(self, req, handler):
        if isinstance(handler, RegistrationModule):
            if not (self.private_key or self.private_key):
                self.log.warning('public_key and private_key under [recaptcha] are '
                                 'not configured. Not showing the reCAPTCHA form!')
                return handler
            self.check_config()
            if req.method == 'POST' and req.args.get('action') == 'create':
                response = captcha.submit(
                    req.args.get('recaptcha_challenge_field'),
                    req.args.get('recaptcha_response_field'),
                    self.private_key, req.remote_addr,
                )
                if not response.is_valid:
                    add_warning(req, 'reCAPTCHA incorrect. Please try again.')
                    req.environ['REQUEST_METHOD'] = 'GET'
                    req.args.pop('password', None)
                    req.args.pop('password_confirm', None)

        # Admin Configuration
        if req.path_info.startswith('/admin/accounts/config') and \
            req.method == 'POST':
            self.config.set('recaptcha', 'lang', req.args.get('recaptcha_lang'))
            self.config.set('recaptcha', 'public_key',
                            req.args.get('recaptcha_public_key'))
            self.config.set('recaptcha', 'private_key',
                            req.args.get('recaptcha_private_key'))
            self.config.set('recaptcha', 'theme',
                            req.args.get('recaptcha_theme'))
            self.config.save()
        return handler
Beispiel #23
0
    def pre_process_request(self, req, handler):
        """Called after initial handler selection, and can be used to change
        the selected handler or redirect request.
        
        Always returns the request handler, even if unchanged.
        """

        if req.path_info.strip('/') == "register":

            if req.method == "POST":
                correct_answer = req.session.pop('captcha', None)
                req.session.save()
                if req.args['captcha'].lower() != correct_answer:

# XXX this bizaarely doesn't work
#                    req.session['captchaauth_message'] = "You typed the wrong word. Please try again."

#                    req.session.save()
                    req.redirect(req.href('register', failed=''))
            if req.method == "GET":
                if 'failed' in req.args:
                    add_warning(req, "You typed the wrong word. Please try again.")

# XXX this bizaarely doesn't work
#                message = req.session.pop('captchaauth_message', None)
#                if message:
#                    add_warning(req, message)
                                    
        return handler
Beispiel #24
0
    def _add_ldap_group(self, req, group_store):
        req.perm.require("PERMISSION_GRANT")

        group_name = req.args.get("group")
        ldap_group_name = req.args.get("ldap_group", "").strip()
        ldap_group_name = ldap_group_name.upper()

        if re.search(r"[^\_A-Z0-9]", ldap_group_name):  # allowed characters
            add_warning(req, "LDAP group name can contain only alphanumeric characters and underline.")
            return

        if not ldap_group_name:
            add_warning(
                req,
                _(
                    "You are trying to add an LDAP group to a user group, "
                    "but you have not specified all the required parameters."
                ),
            )
            return

        group_store.add_ldapgroup_to_group(ldap_group_name, group_name)
        add_notice(
            req, _("LDAP group %(who)s has been added to group %(where)s.", who=ldap_group_name, where=group_name)
        )
Beispiel #25
0
 def save(self, req):
     if req.args and req.args.has_key('action') \
     and req.args['action'] == 'save':
         for key in SESSION_KEYS.values():
             if req.args.has_key(key):
                 if key == 'wiki.href':
                     wiki_href = req.args[key]
                     if wiki_href == '':
                         req.session[key] = ''
                         continue
                     validated = WikiSystem(self.env).has_page(wiki_href)
                     if validated:
                         req.session[key] = req.args[key]
                     else:
                         add_warning(req, Markup(tag.span(Markup(_(
                             "%(page)s is not a valid Wiki page",
                             page=tag.b(wiki_href)
                             )))))
                 elif key == 'tickets.href':
                     ticket_href = req.args[key]
                     if ticket_href == '':
                         req.session[key] = ''
                         continue
                     reports = self.get_report_list()
                     self.log.info('reports: %s' % reports)
                     if ticket_href in ('report', 'query') \
                     or as_int(ticket_href, 0) in reports:
                         req.session[key] = req.args[key]
                     else:
                         add_warning(req, Markup(tag.span(Markup(_(
                             "%(report)s is not a valid report",
                             report=tag.b(ticket_href)
                             )))))
                 else:
                     req.session[key] = req.args[key]
Beispiel #26
0
 def pre_process_request(self, req, handler):
     # TODO Ugly set of conditions, make the if beautiful
     if req.path_info.startswith('/browser') and req.method == 'POST' \
             and ('bsop_upload_file' in req.args
                  or 'bsop_mvdel_op' in req.args
                  or 'bsop_create_folder_name' in req.args):
         req.perm.require('REPOSITORY_MODIFY')
         
         self.log.debug('Intercepting browser POST')
         
         # Dispatch to private handlers based on which form submitted
         # The handlers perform a redirect, so don't return the handler
         try:
             if 'bsop_upload_file' in req.args:
                 self._upload_request(req, handler)
             elif 'bsop_mvdel_op' in req.args:
                 self._move_delete_request(req, handler)
             elif 'bsop_create_folder_name' in req.args:
                 self._create_path_request(req, handler)
         except PermissionError, e:
             add_warning(req, "Permission denied")
             req.redirect(req.href(req.path_info))
         except RequestDone:
             # Raised from redirect in successful operations above, we don't want it caught
             # by the below general except.
             raise
Beispiel #27
0
    def post_process_request(self, req, template, data, content_type):
        """Do any post-processing the request might need; typically adding
        values to the template `data` dictionary, or changing template or
        mime type.
        
        `data` may be update in place.

        Always returns a tuple of (template, data, content_type), even if
        unchanged.

        Note that `template`, `data`, `content_type` will be `None` if:
         - called when processing an error page
         - the default request handler did not return any result

        (Since 0.11)
        """

        if template != "query.html":
            return (template, data, content_type)

        geoticket = self.geoticket()
        location = req.args.get("center_location", "").strip()
        lat = lon = None
        if location:
            try:
                location, (lat, lon) = geoticket.geolocate(location)
            except GeolocationException, e:
                add_script(req, "geoticket/js/query_location_filler.js")
                add_warning(req, Markup(e.html()))
Beispiel #28
0
    def post_process_request(self, req, template, data, content_type):
        """Do any post-processing the request might need; typically adding
        values to the template `data` dictionary, or changing template or
        mime type.
        
        `data` may be update in place.

        Always returns a tuple of (template, data, content_type), even if
        unchanged.

        Note that `template`, `data`, `content_type` will be `None` if:
         - called when processing an error page
         - the default request handler did not return any result

        (Since 0.11)
        """

        if template == 'ticket.html':
            geoticket = GeoTicket(self.env)
            ticket = data['ticket']
            message = req.session.pop('geolocation_error', None)
            if message:
                add_warning(req, Markup(message))

        return (template, data, content_type)
Beispiel #29
0
    def query(self, req, query="", attribute_handlers=None):
        """Return a sequence of (resource, tags) tuples matching a query.

        Query syntax is described in tractags.query.

        :param attribute_handlers: Register additional query attribute
                                   handlers. See Query documentation for more
                                   information.
        """

        def realm_handler(_, node, context):
            return query.match(node, [context.realm])

        all_attribute_handlers = {"realm": realm_handler}
        all_attribute_handlers.update(attribute_handlers or {})
        if re.search(r"(expression|tagspace|tagspaces|operation|showheadings" "|expression)=", query):
            message = Markup(
                "You seem to be using an old Tag query. "
                'Try using the <a href="%s">new syntax</a> in your '
                "<strong>ListTagged</strong> macro.",
                req.href("tags"),
            )
            add_warning(req, message)
        query = Query(query, attribute_handlers=all_attribute_handlers)

        query_tags = set(query.terms())
        for provider in self.tag_providers:
            for resource, tags in provider.get_tagged_resources(req, query_tags):
                if query(tags, context=resource):
                    yield resource, tags
Beispiel #30
0
 def post_process_request(self, req, template, data, content_type):
     if (template, data) != (None, None) or \
             sys.exc_info() != (None, None, None):
         try:
             theme = self.system.theme
         except ThemeNotFound, e:
             add_warning(req, "Unknown theme %s configured. Please check "
                     "your trac.ini. You may need to enable "
                     "the theme\'s plugin." % e.theme_name)
         else:
             if theme and 'css' in theme:
                 add_stylesheet(req, 'theme/'+theme['css'])
             if theme and 'template' in theme:
                 req.chrome['theme'] = os.path.basename(theme['template'])
             if theme and theme.get('disable_trac_css'):
                 links = req.chrome.get('links')
                 if links and 'stylesheet' in links:
                     for i, link in enumerate(links['stylesheet']):
                         if link.get('href','') \
                                 .endswith('common/css/trac.css'):
                             del links['stylesheet'][i]
                             break
             if theme:
                 # Template overrides (since 2.2.0)
                 overrides = self._get_template_overrides(theme)
                 template, modifier = overrides.get(template, 
                                                    (template, None))
                 if modifier is not None:
                     modifier(req, template, data, content_type)
         if self.custom_css:
             add_stylesheet(req, '/themeengine/theme.css')
    def _add_organization(self, req, group_store):
        req.perm.require('PERMISSION_GRANT')

        group_name = req.args.get('group')
        organization = req.args.get('organization')

        try:
            group_store.add_organization_to_group(organization, group_name)
            add_notice(
                req,
                _('Organization %(organization)s added to group %(group)s',
                  group=group_name,
                  organization=organization))
        except ValueError:
            add_warning(
                req,
                _('Organization %(organization)s already exists in group %(group)s',
                  group=group_name,
                  organization=organization))
Beispiel #32
0
Datei: batch.py Projekt: t2y/trac
 def _save_ticket_changes(self, req, selected_tickets, new_values, comment,
                          action):
     """Save all of the changes to tickets."""
     when = datetime.now(utc)
     list_fields = self._get_list_fields()
     with self.env.db_transaction as db:
         for id in selected_tickets:
             t = Ticket(self.env, int(id))
             _values = new_values.copy()
             for field in list_fields:
                 if field in new_values:
                     old = t.values[field] if field in t.values else ''
                     new = new_values[field]
                     mode = req.args.get('batchmod_value_' + field +
                                         '_mode')
                     new2 = req.args.get(
                         'batchmod_value_' + field + '_secondary', '')
                     _values[field] = self._change_list(
                         old, new, new2, mode)
             controllers = list(self._get_action_controllers(
                 req, t, action))
             for controller in controllers:
                 _values.update(
                     controller.get_ticket_changes(req, t, action))
             t.populate(_values)
             t.save_changes(req.authname, comment, when=when)
             for controller in controllers:
                 controller.apply_action_side_effects(req, t, action)
     try:
         tn = BatchTicketNotifyEmail(self.env)
         tn.notify(selected_tickets, new_values, comment, action,
                   req.authname)
     except Exception as e:
         self.log.error(
             "Failure sending notification on ticket batch"
             "change: %s", exception_to_unicode(e))
         add_warning(
             req,
             tag_(
                 "The changes have been saved, but an "
                 "error occurred while sending "
                 "notifications: %(message)s",
                 message=to_unicode(e)))
    def _send_response(self, req, data):
        """Send the response."""

        # look for warnings
        if not len(self.providers):
            add_warning(
                req,
                _('No advanced search providers found. ' +
                  'You must register a search backend.'))

        if data.get('results') and not len(data['results']):
            add_warning(req, _('No results.'))

        add_stylesheet(req, 'common/css/search.css')
        add_stylesheet(req, 'advsearch/css/advsearch.css')
        add_stylesheet(req, 'advsearch/css/pikaday.css')
        add_script(req, 'advsearch/js/advsearch.js')
        add_script(req, 'advsearch/js/pikaday.js')
        return 'advsearch.html', data, None
    def _reset_password(self, req, username, email):
        """Store a new, temporary password on admin or user request.

        This method is used by acct_mgr.admin.AccountManagerAdminPanel too.
        """
        acctmgr = self.acctmgr
        new_password = self._random_password
        try:
            self.store.set_password(username, new_password)
            acctmgr._notify('password_reset', username, email, new_password)
        except NotificationError, e:
            msg = _("Error raised while sending a change notification.")
            if req.path_info.startswith('/admin'):
                msg += _("You'll get details with TracLogging enabled.")
            else:
                msg += _("You should report that issue to a Trac admin.")
            add_warning(req, msg)
            self.log.error("Unable to send password reset notification: %s",
                           exception_to_unicode(e, traceback=True))
Beispiel #35
0
    def merge_to_category(self, req):
        req.perm.require('TRAC_ADMIN')

        # possible params involved in req: target_category_name, target_category_id
        target_category = self._translate_req_to_category(req, 'target')
        # possible params involved in req: merged_category_id, merged_category_name
        merged_category = self._translate_req_to_category(req, 'merged')
        if not target_category or not merged_category:
            add_warning(req, _('Invalid merge category parameters: No corresponding category found.'))
            return

        try:
            self.categorystore.merge_category_to_category(merged_category.category_id,
                target_category.category_id)
            add_notice(req, _('Category %(merged)s has been merged to %(target)s.',
                merged = merged_category.name, target = target_category.name))
        except Exception as e:
            add_warning(req, _('Category %(what)s was not merged. ',
                what=merged_category.name) + _(str(e)))
Beispiel #36
0
    def _save_ticket_changes(self, req, selected_tickets, new_values, comment,
                             action):
        """Save changes to tickets."""
        valid = True
        for manipulator in self.ticket_manipulators:
            if hasattr(manipulator, 'validate_comment'):
                for message in manipulator.validate_comment(req, comment):
                    valid = False
                    add_warning(req, tag_("The ticket comment is invalid: "
                                          "%(message)s",
                                          message=message))

        tickets = []
        for id_ in selected_tickets:
            t = Ticket(self.env, id_)
            values = self._get_updated_ticket_values(req, t, new_values)
            for ctlr in self._get_action_controllers(req, t, action):
                values.update(ctlr.get_ticket_changes(req, t, action))
            t.populate(values)
            for manipulator in self.ticket_manipulators:
                for field, message in manipulator.validate_ticket(req, t):
                    valid = False
                    if field:
                        add_warning(req, tag_("The ticket field %(field)s is "
                                              "invalid: %(message)s",
                                              field=tag.strong(field),
                                              message=message))
                    else:
                        add_warning(req, message)
            tickets.append(t)

        if not valid:
            return

        when = datetime_now(utc)
        with self.env.db_transaction:
            for t in tickets:
                t.save_changes(req.authname, comment, when=when)
                for ctlr in self._get_action_controllers(req, t, action):
                    ctlr.apply_action_side_effects(req, t, action)

        event = BatchTicketChangeEvent(selected_tickets, when,
                                       req.authname, comment, new_values,
                                       action)
        try:
            NotificationSystem(self.env).notify(event)
        except Exception as e:
            self.log.error("Failure sending notification on ticket batch"
                           "change: %s", exception_to_unicode(e))
            add_warning(req,
                        tag_("The changes have been saved, but an error "
                             "occurred while sending notifications: "
                             "%(message)s", message=to_unicode(e)))
Beispiel #37
0
 def post_process_request(self, req, template, data, mimetype):
     if self.delegate:
         add_link(req, 'openid.delegate', self.delegate)
         server = self.server
         if not server:
             for id_regex, server_href in self.known_servers.iteritems():
                 if id_regex.search(self.delegate):
                     server = server_href
                     break
             else:
                 add_warning(req, 'OpenID for identity %s unknown.',
                                  self.delegate)
                 return template, data, mimetype
         add_link(req, 'openid.server', server)
         
     elif 'TRAC_ADMIN' in req.perm:
         # Warn admins if the plugin is enabled, but not configured
         add_warning(req, 'No OpenID identity specified for delegation.')
     return template, data, mimetype
Beispiel #38
0
    def _upload_request(self, req, handler):
        self.log.debug('Handling file upload for "%s"', req.authname)

        # Retrieve uploaded file
        upload_file = req.args['bsop_upload_file']

        # Retrieve filename, normalize, use to check a file was uploaded
        # Filename checks adapted from trac/attachment.py
        filename = getattr(upload_file, 'filename', '')
        filename = unicodedata.normalize('NFC', unicode(filename, 'utf-8'))
        filename = filename.replace('\\', '/').replace(':', '/')
        filename = posixpath.basename(filename)
        if not filename:
            raise TracError('No file uploaded')

        # Check size of uploaded file, accepting 0 to max_upload_size bytes
        file_data = upload_file.value  # Alternatively .file for file object
        file_size = len(file_data)
        if self.max_upload_size > 0 and file_size > self.max_upload_size:
            raise TracError('Uploaded file is too large, '
                            'maximum upload size: %s' %
                            pretty_size(self.max_upload_size))

        self.log.debug('Received file %s with %i bytes', filename, file_size)

        commit_msg = req.args.get('bsop_upload_commit')

        self.log.debug('Opening repository for file upload')
        reponame, repos, path = _get_repository(self.env, req)
        try:
            repos_path = repos.normalize_path('/'.join([path, filename]))
            self.log.debug('Writing file %s to %s in %s', filename, repos_path,
                           reponame)
            svn_writer = SubversionWriter(self.env, repos, req.authname)

            rev = svn_writer.put_content(repos_path, file_data, commit_msg)
            add_notice(
                req,
                _("Uploaded %s, creating revision %s.") % (filename, rev))
        except Exception, e:
            self.log.exception("Failed when uploading file %s" % filename)
            add_warning(req, _("Failed to upload file: %s") % e)
Beispiel #39
0
    def _do_delete(self, req, milestone):
        req.perm(milestone.resource).require('MILESTONE_DELETE')

        retarget_to = req.args.get('target') or None
        # Don't translate ticket comment (comment:40:ticket:5658)
        retargeted_tickets = \
            milestone.move_tickets(retarget_to, req.authname,
                "Ticket retargeted after milestone deleted")
        milestone.delete()
        add_notice(
            req,
            _('The milestone "%(name)s" has been deleted.',
              name=milestone.name))
        if retargeted_tickets:
            add_notice(
                req,
                _(
                    'The tickets associated with milestone '
                    '"%(name)s" have been retargeted to milestone '
                    '"%(retarget)s".',
                    name=milestone.name,
                    retarget=retarget_to))
            new_values = {'milestone': retarget_to}
            comment = _("Tickets retargeted after milestone deleted")
            event = BatchTicketChangeEvent(retargeted_tickets, None,
                                           req.authname, comment, new_values,
                                           None)
            try:
                NotificationSystem(self.env).notify(event)
            except Exception as e:
                self.log.error(
                    "Failure sending notification on ticket batch "
                    "change: %s", exception_to_unicode(e))
                add_warning(
                    req,
                    tag_(
                        "The changes have been saved, but an "
                        "error occurred while sending "
                        "notifications: %(message)s",
                        message=to_unicode(e)))

        req.redirect(req.href.roadmap())
Beispiel #40
0
    def render_admin_panel(self, req, cat, page, path_info):
        req.perm.require("TRAC_ADMIN")
        arch = ProjectArchive()
        projects = arch.list()

        if req.method == 'POST':
            archived_project_id = int(req.args.get('archived_project_id', 0))
            action = req.args.get('action', 'noop')

            try:
                if action == 'restore':
                    if arch.restore(archived_project_id, self.env):
                        add_notice(req, _('Restored project successfully'))

                elif action == 'remove':
                    if arch.remove(archived_project_id):
                        add_notice(req, _('Removed project successfully'))

                elif action == 'remove_expired':
                    if arch.remove_expired():
                        add_notice(req,
                                   _('Removed expired projects successfully'))

                else:
                    add_warning(req, _('Unknown action'))

            except Exception:
                add_warning(req, _('Failed to complete the action'))
                self.log.exception('Failed to {0} for project {1}'.format(
                    action, archived_project_id))

            # After post method, redirect back to listing
            return req.redirect(req.href('/admin/projects/prjarchive'))

        add_script(req, 'multiproject/js/jquery-ui.js')
        add_stylesheet(req, 'multiproject/css/jquery-ui.css')
        add_script(req, 'multiproject/js/multiproject.js')
        add_script(req, 'multiproject/js/admin_project_archive.js')

        return 'multiproject_admin_project_archive.html', {
            'projects': projects
        }
Beispiel #41
0
    def _add_path(self, req):
        path = req.args.get('path')
        repository = None
        tmppath = req.args.get('path')

        if ":" in tmppath:
            repository, path = tmppath.split(":")
            repository = repository.strip()
            path = path.strip()
        else:
            repository = self.project_repos[0]
            path = tmppath.strip()
        if not path:
            add_warning(req, "Path not specified")
            return {} 
        try:
            self.authz.add_path(Path(path, [], repository))
            return {}
        except Exception, e:
            return {'addpath_error' :  e}
Beispiel #42
0
    def _save_config(self, req, notices=None):
        """Try to save the config, and display either a success notice or a
        failure warning.
        """
        try:

            self.cronconf.save()

            if notices is None:
                notices = [_('Your changes have been saved.')]
            for notice in notices:
                add_notice(req, notice)
        except Exception, e:
            self.env.log.error('Error writing to trac.ini: %s',
                               exception_to_unicode(e))
            add_warning(
                req,
                _('Error writing to trac.ini, make sure it is '
                  'writable by the web server. Your changes have '
                  'not been saved.'))
Beispiel #43
0
 def pre_process_request(self, req, handler):
     if not req.session.authenticated:
         # Permissions for anonymous users remain unchanged.
         return handler
     if AccountManager(self.env).verify_email and handler is not self and \
             'email_verification_token' in req.session and \
             not req.perm.has_permission('ACCTMGR_ADMIN'):
         # TRANSLATOR: Your permissions have been limited until you ...
         link = tag.a(_("verify your email address"),
                      href=req.href.verify_email())
         # TRANSLATOR: ... verify your email address
         chrome.add_warning(
             req,
             Markup(
                 tag.span(
                     Markup(
                         _("Your permissions have been limited until you %(link)s.",
                           link=link)))))
         req.perm = perm.PermissionCache(self.env, 'anonymous')
     return handler
Beispiel #44
0
 def process_request(self, req):
     """Process the HTTP Requests and validate parameters, at least 
     basically, than send a Command Request to a Controller. The 
     response has to be rendered according to the view needs."""
     try:
         handler = self.get_handler(req)
         if handler is not None:
             return self._call_filters_and_handler(req, handler)
         else:
             raise TracError('No handler found for method %s' % req.method)
     except ICommand.NotValidError, e:
         chrome.add_warning(req, unicode(e))
         # not that we update the data, so that the set value are
         # kept safe for re-displaying a page correctly
         data = self.get_data_from_session(req)
         data.update({'error': unicode(e)})
         # This will allow to show the wrong field in a different
         # color or mark them as errors
         data.update({'errors': e.command_attributes.keys()})
         return self.respond(data)
Beispiel #45
0
    def pre_process_request(self, req, handler):
        if isinstance(handler, RegistrationModule):
            if req.method == 'POST' and req.args.get(
                    'action') == 'create' and req.args.get('question').strip(
                    ).lower() != self.answer.strip().lower():
                add_warning(req, self.hint)
                req.environ['REQUEST_METHOD'] = 'GET'
                req.args.pop('password', None)
                req.args.pop('password_confirm', None)

        # Admin Configuration
        if req.path_info.startswith('/admin/accounts/config') and \
            req.method == 'POST':
            self.config.set('registerquestion', 'question',
                            req.args.get('question'))
            self.config.set('registerquestion', 'answer',
                            req.args.get('answer'))
            self.config.set('registerquestion', 'hint', req.args.get('hint'))
            self.config.save()
        return handler
Beispiel #46
0
    def render_admin_panel(self, req, cat, page, path_info):
        wikipages = urllib.unquote_plus(req.args.get('wikipages', ''))
        parts = wikipages.splitlines()

        data = {
            'find': urllib.unquote_plus(req.args.get('find', '')),
            'replace': urllib.unquote_plus(req.args.get('replace', '')),
            'wikipages': parts,
            'redir': req.args.get('redirect', '') == '1',
        }

        if req.method == 'POST':
            # Check that required fields are filled in.
            if not data['find']:
                add_warning(req,
                            'The Find field was empty. Nothing was changed.')
            if not data['wikipages'] or not data['wikipages'][0]:
                add_warning(
                    req,
                    'The Wiki pages field was empty. Nothing was changed.')

            # Replace the text if the find and wikipages fields have been input.
            if data['find'] and data['wikipages'] and data['wikipages'][0]:
                add_notice(
                    req,
                    'Replaced "%s" with "%s". See the timeline for modified pages.'
                    % (data['find'], data['replace']))
                wiki_text_replace(self.env,
                                  data['find'],
                                  data['replace'],
                                  data['wikipages'],
                                  req.authname,
                                  req.remote_addr,
                                  debug=self.log.debug)

            # Reset for the next display
            data['find'] = ''
            data['replace'] = ''
            data['wikipages'] = ''

        return 'admin_wikireplace.html', data
Beispiel #47
0
    def _process_remove_request(self, req, data):
        """Remove an existing repository."""
        repo = self._get_checked_repository(req, req.args.get('reponame'))

        open_ticket = None
        with self.env.db_transaction as db:
            tickets = db("""SELECT ticket FROM (
                                SELECT src.ticket,
                                       src.value as srcrepo,
                                      dst.value as dstrepo
                                FROM ticket_custom AS src JOIN
                                     ticket_custom AS dst ON
                                     (src.ticket = dst.ticket)
                                WHERE src.name = 'pr_srcrepo' AND
                                      dst.name = 'pr_dstrepo')
                            WHERE srcrepo = %d OR dstrepo = %d
                            """ % (repo.id, repo.id))
            for values in tickets:
                (id,) = values
                ticket = Ticket(self.env, id)
                if ticket['status'] != 'closed':
                    open_ticket = id
                    break

        if open_ticket:
            link = tag.a(_("pull request"), href=req.href.ticket(open_ticket))
            add_warning(req, tag_('The repository "%(name)s can not be '
                                  'removed as it is referenced by an open '
                                  '%(link)s.', name=repo.reponame, link=link))
            LoginModule(self.env)._redirect_back(req)

        if req.args.get('confirm'):
            RepositoryManager(self.env).remove(repo, req.args.get('delete'))
            add_notice(req, _('The repository "%(name)s" has been removed.',
                              name=repo.reponame))
            req.redirect(req.href.repository())
        elif req.args.get('cancel'):
            LoginModule(self.env)._redirect_back(req)

        data.update({'title': _("Remove Repository"),
                     'repository': repo})
 def post_process_request(self, req, template, data, content_type):
     if (template, data) != (None, None) or \
             sys.exc_info() != (None, None, None):
         try:
             theme = self.system.theme
         except ThemeNotFound, e:
             add_warning(
                 req, "Unknown theme %s configured. Please check "
                 "your trac.ini. You may need to enable "
                 "the theme\'s plugin." % e.theme_name)
         else:
             if theme and 'css' in theme:
                 add_stylesheet(req, 'theme/' + theme['css'])
             if theme and 'template' in theme:
                 req.chrome['theme'] = os.path.basename(theme['template'])
             if theme and 'scripts' in theme:
                 for script_def in theme['scripts']:
                     if (isinstance(script_def, tuple)
                             and 1 <= len(script_def) <= 4):
                         add_script(req, *script_def)
                     else:
                         self.log.warning('Bad script def %s for theme %s',
                                          script_def, theme['name'])
             if theme and theme.get('disable_trac_css'):
                 links = req.chrome.get('links')
                 if links and 'stylesheet' in links:
                     for i, link in enumerate(links['stylesheet']):
                         if link.get('href', '') \
                                 .endswith('common/css/trac.css'):
                             del links['stylesheet'][i]
                             break
             if theme:
                 req.chrome['theme_info'] = theme
                 # Template overrides (since 2.2.0)
                 overrides = self._get_template_overrides(theme)
                 template, modifier = overrides.get(template,
                                                    (template, None))
                 if modifier is not None:
                     modifier(req, template, data, content_type)
         if self.custom_css:
             add_stylesheet(req, 'site/theme.css')
Beispiel #49
0
 def _do_account(self, req):
     if not req.authname or req.authname == 'anonymous':
         # DEVEL: Shouldn't this be a more generic URL?
         req.redirect(req.href.wiki())
     action = req.args.get('action')
     delete_enabled = self.acctmgr.supports('delete_user') and \
                          self.acctmgr.allow_delete_account
     data = {
         'delete_enabled':
         delete_enabled,
         'delete_msg_confirm':
         _("Are you sure you want to delete your account?"),
     }
     force_change_password = req.session.get('force_change_passwd', False)
     if req.method == 'POST':
         if action == 'save':
             data.update(self._do_change_password(req))
             if force_change_password:
                 del (req.session['force_change_passwd'])
                 req.session.save()
                 chrome.add_notice(
                     req,
                     Markup(
                         tag.span(
                             tag_(
                                 "Thank you for taking the time to update your password."
                             ))))
                 force_change_password = False
         elif action == 'delete' and delete_enabled:
             data.update(self._do_delete(req))
         else:
             data.update({'error': 'Invalid action'})
     if force_change_password:
         chrome.add_warning(
             req,
             Markup(
                 tag.span(
                     _("You are required to change password because of a recent "
                       "password change request. "),
                     tag.b(_("Please change your password now.")))))
     return data
Beispiel #50
0
    def _do_save(self, req, page):
        if not page.exists:
            req.perm(page.resource).require('WIKI_CREATE')
        else:
            req.perm(page.resource).require('WIKI_MODIFY')

        if 'WIKI_ADMIN' in req.perm(page.resource):
            # Modify the read-only flag if it has been changed and the user is
            # WIKI_ADMIN
            page.readonly = int('readonly' in req.args)

        try:
            page.save(get_reporter_id(req, 'author'), req.args.get('comment'),
                      req.remote_addr)
            add_notice(req, _("Your changes have been saved in version "
                              "%(version)s.", version=page.version))
            req.redirect(get_resource_url(self.env, page.resource, req.href,
                                          version=None))
        except TracError:
            add_warning(req, _("Page not modified, showing latest version."))
            return self._render_view(req, page)
    def _do_delete(self, req):
        username = req.authname

        password = req.args.get('password')
        if not password:
            add_warning(req, _("Password cannot be empty."))
        elif not self.acctmgr.check_password(username, password):
            add_warning(req, _("Password is incorrect."))
        else:
            try:
                self.acctmgr.delete_user(username)
            except NotificationError, e:
                # User wont care for notification, only care for logging here.
                self.log.error(
                    "Unable to send account deletion notification: "
                    "%s", exception_to_unicode(e, traceback=True))
            # Delete the whole session, since records in session_attribute
            # would get restored on logout otherwise.
            req.session.clear()
            req.session.save()
            req.redirect(req.href.logout())
Beispiel #52
0
    def process_post(self, hookname, req):

        contents = req.args.get('hook-file-contents', None)
        if contents is None:
            return
        if os.linesep != CRLF:
            contents = os.linesep.join(
                contents.split(CRLF))  # form contents will have this

        filename = self.filename(hookname)
        if not os.path.exists(filename):
            if not iswritable(filename):
                add_warning(req, 'File "%s" not writable' % filename)
                return
        f = file(filename, 'w')
        print >> f, contents
        f.close()
        try:
            os.chmod(filename, self.mode)
        except:  # won't work on winblows
            pass
Beispiel #53
0
 def process_delete(self, action, node, node_factory, req, timeline_notifier):
     selected_files = self._get_selected_files(req, node, action == 'delete')
     successful_files = 0
     target_node = None
     for filename in selected_files:
         relative_path = os.path.join(node.relative_path, filename)
         removed_node = MappedFileNode.from_path(relative_path, node_factory,
             assume_relative_path=True)
         try:
             removed_node.remove_by_request(req, timeline_notifier)
             successful_files += 1
         except TracError as e:
             add_warning(req, _("Could not remove file or folder %(filename)s: ",
                 filename=filename) + str(e))
     if len(selected_files) == 1 and successful_files == 1:
         add_notice(req, _("Removed file %(filename)s successfully",
             filename=selected_files[0]))
     elif successful_files and successful_files == len(selected_files):
         add_notice(req, _("Removed files successfully"))
     elif successful_files:
         add_notice(req, _("Removed other files successfully"))
    def _create_group(self, req, group_store, perm_sys):
        req.perm.require('PERMISSION_GRANT')

        group_perms = req.args.get('group_perms')
        group_name = req.args.get('group_name')

        # if only one permission selected
        if isinstance(group_perms, basestring):
            group_perms = [group_perms]

        if not group_name:
            add_warning(req, _('Invalid group name'))
            return

        # trac schema limitation
        if group_name.isupper():
            add_warning(req, _('Group name cannot be in all upper cases'))
            return

        valid_perms = perm_sys.get_actions()
        for perm in group_perms:
            if perm not in valid_perms:
                raise TracError('Invalid permission %s' % perm)
            try:
                group_store.grant_permission_to_group(group_name, perm)
            except InvalidPermissionsState, e:
                add_warning(
                    req,
                    _('Unable to add permission %(perm)s to group %(group)s. %(reason)s',
                      perm=perm,
                      group=group_name,
                      reason=e.message))
    def _do_save(self, req, user):
        """ Update user information into database
        """
        userstore = get_userstore()

        if not req.args.get('mail'):
            add_warning(req, _('User should have an e-mail address'))
            return user

        user.mail = req.args.get('mail')

        if not req.args.get('lastName'):
            add_warning(req, _('Last name required'))
            return user

        # NOTE: Values are escaped in userstore update
        user.lastName = req.args.get('lastName')
        user.givenName = req.args.get('givenName')
        user.mobile = req.args.get('mobile')

        if userstore.updateUser(user):
            user = userstore.getUser(user.username)
            add_notice(req, _('Updated user settings'))

            if req.args.get(
                    'approve') == 'on' and user.status == user.STATUS_INACTIVE:
                user.activate()
                add_notice(req, _("Your account is now activated."))

            return user

        add_warning(req, _('Failed to update user'))
        return user
Beispiel #56
0
    def _validate(self, req, page):
        valid = True

        # Validate page size
        if len(req.args.get('text', '')) > self.max_size:
            add_warning(
                req,
                _(
                    'The wiki page is too long (must be less '
                    'than %(num)s characters)',
                    num=self.max_size))
            valid = False

        # Give the manipulators a pass at post-processing the page
        for manipulator in self.page_manipulators:
            for field, message in manipulator.validate_wiki_page(req, page):
                valid = False
                if field:
                    add_warning(
                        req,
                        tag_(
                            "The Wiki page field %(field)s"
                            " is invalid: %(message)s",
                            field=tag.strong(field),
                            message=message))
                else:
                    add_warning(
                        req,
                        tag_("Invalid Wiki page: %(message)s",
                             message=message))
        return valid
Beispiel #57
0
    def _do_rename(self, req, page):
        if page.readonly:
            req.perm(page.resource).require('WIKI_ADMIN')
        else:
            req.perm(page.resource).require('WIKI_RENAME')

        if 'cancel' in req.args:
            req.redirect(get_resource_url(self.env, page.resource, req.href))

        old_name, old_version = page.name, page.version
        new_name = req.args.get('new_name', '')
        new_name = re.sub(r'/{2,}', '/', new_name.strip('/'))
        redirect = req.args.get('redirect')

        # verify input parameters
        warn = None
        if not new_name:
            warn = _("A new name is mandatory for a rename.")
        elif not validate_page_name(new_name):
            warn = _("The new name is invalid (a name which is separated "
                     "with slashes cannot be '.' or '..').")
        elif new_name == old_name:
            warn = _("The new name must be different from the old name.")
        elif WikiPage(self.env, new_name).exists:
            warn = _("The page %(name)s already exists.", name=new_name)
        if warn:
            add_warning(req, warn)
            return self._render_confirm_rename(req, page, new_name)

        with self.env.db_transaction as db:
            page.rename(new_name)
            if redirect:
                redirection = WikiPage(self.env, old_name, db=db)
                redirection.text = _('See [wiki:"%(name)s"].', name=new_name)
                author = get_reporter_id(req)
                comment = u'[wiki:"%s@%d" %s] \u2192 [wiki:"%s"].' % (
                    new_name, old_version, old_name, new_name)
                redirection.save(author, comment, req.remote_addr)

        req.redirect(req.href.wiki(old_name if redirect else new_name))
Beispiel #58
0
    def create_failure(self, req, msg):
        author = get_context(req)['author']

        data = {}
        data['url'] = ProjectListModule.url
        data['home'] = req.base_path
        data['user'] = author
        data['vcslist'] = self._list_enabled_vcs()
        data['prj_is_public'] = sanitize_html(
            req.args.get('prj_is_public', 'off'))

        # Use system warning to notify user
        add_warning(req, msg)

        for key in req.args:
            if key in [
                    'prj_long_name', 'prj_short_name', 'prj_description',
                    'vcstype', '_project_'
            ]:
                data[key] = sanitize_html(req.args[key])

        return 'create_form.html', data, None
Beispiel #59
0
 def _check_dir(self, req, dir):
     """Check that a repository directory is valid, and add a warning
     message if not.
     """
     if not os.path.isabs(dir):
         add_warning(
             req, _('The repository directory must be an absolute path.'))
         return False
     prefixes = [
         os.path.join(self.env.path, prefix)
         for prefix in self.allowed_repository_dir_prefixes
     ]
     if prefixes and not any(
             util.is_path_below(dir, prefix) for prefix in prefixes):
         add_warning(
             req,
             _(
                 'The repository directory must be located below one of the following directories: '
                 '%(dirs)s',
                 dirs=', '.join(prefixes)))
         return False
     return True
Beispiel #60
0
    def render_admin_panel(self, req, cat, page, version):
        req.perm.require('TAGS_ADMIN')

        tag_system = TagSystem(self.env)
        all_realms = tag_system.get_taggable_realms(req.perm)
        # Check request for enabled filters, or use default.
        if not [r for r in all_realms if r in req.args]:
            for realm in all_realms:
                req.args[realm] = 'on'
        checked_realms = [r for r in all_realms if r in req.args]
        data = dict(checked_realms=checked_realms,
                    tag_realms=list(dict(name=realm,
                                         checked=realm in checked_realms)
                                    for realm in all_realms))

        if req.method == 'POST':
            # Replace Tag
            allow_delete = req.args.get('allow_delete')
            new_tag = req.args.get('tag_new_name').strip()
            new_tag = not new_tag == u'' and new_tag or None
            if not (allow_delete or new_tag):
                add_warning(req, _("Selected current tag(s) and either "
                                   "new tag or delete approval are required"))
            else:
                comment = req.args.get('comment', u'')
                old_tags = req.args.getlist('tag_name')
                if old_tags:
                    tag_system.replace_tag(req, old_tags, new_tag, comment,
                                           allow_delete, filter=checked_realms)
                data['selected'] = new_tag
            req.redirect(req.href.admin('tags', 'replace'))

        query = ' or '.join('realm:%s' % r for r in checked_realms)
        all_tags = sorted(tag_system.get_all_tags(req, query))
        data['tags'] = all_tags
        chrome = Chrome(self.env)
        chrome.add_textarea_grips(req)

        return 'admin_tag_change.html', data, {'domain': 'tractags'}