Switch to unified view

a/Allura/allura/app.py b/Allura/allura/app.py
...
...
26
from bson import ObjectId
26
from bson import ObjectId
27
27
28
from ming.orm import session, state
28
from ming.orm import session, state
29
from ming.utils import LazyProperty
29
from ming.utils import LazyProperty
30
30
31
from allura.lib.helpers import push_config, vardec
31
from allura.lib import helpers as h
32
from allura.lib.security import require, has_access, require_access
32
from allura.lib.security import require, has_access, require_access
33
from allura import model
33
from allura import model
34
from allura.controllers import BaseController
34
from allura.controllers import BaseController
35
from allura.lib.decorators import require_post, event_handler
35
from allura.lib.decorators import require_post, event_handler
36
from allura.lib.utils import permanent_redirect
36
from allura.lib.utils import permanent_redirect
...
...
142
    :cvar bool installable: Default is True, Application can be installed in
142
    :cvar bool installable: Default is True, Application can be installed in
143
        projects.
143
        projects.
144
    :cvar bool hidden: Default is False, Application is not hidden from the
144
    :cvar bool hidden: Default is False, Application is not hidden from the
145
        list of a project's installed tools.
145
        list of a project's installed tools.
146
    :cvar str tool_description: Text description of this Application.
146
    :cvar str tool_description: Text description of this Application.
147
    :cvar bool relaxed_mount_points: Set to True to relax the default mount point
148
        naming restrictions for this Application. Default is False. See
149
        :attr:`default mount point naming rules <allura.lib.helpers.re_tool_mount_point>` and
150
        :attr:`relaxed mount point naming rules <allura.lib.helpers.re_relaxed_tool_mount_point>`.
147
    :cvar Controller root: Serves content at
151
    :cvar Controller root: Serves content at
148
        /<neighborhood>/<project>/<app>/. Default is None - subclasses should
152
        /<neighborhood>/<project>/<app>/. Default is None - subclasses should
149
        override.
153
        override.
150
    :cvar Controller api_root: Serves API access at
154
    :cvar Controller api_root: Serves API access at
151
        /rest/<neighborhood>/<project>/<app>/. Default is None - subclasses
155
        /rest/<neighborhood>/<project>/<app>/. Default is None - subclasses
152
        should override to expose API access to the Application.
156
        should override to expose API access to the Application.
153
    :ivar Controller admin: Serves admin functions at
157
    :ivar Controller admin: Serves admin functions at
154
        /<neighborhood>/<project>/<admin>/<app>/. Default is a
158
        /<neighborhood>/<project>/<admin>/<app>/. Default is a
155
        :class:`DefaultAdminController` instance.
159
        :class:`DefaultAdminController` instance.
156
    :cvar dict icons: Mapping of icon sizes to application-specific icon paths.
160
    :cvar dict icons: Mapping of icon sizes to application-specific icon paths.
157
158
    """
161
    """
159
162
160
    __version__ = None
163
    __version__ = None
161
    config_options = [
164
    config_options = [
162
        ConfigOption('mount_point', str, 'app'),
165
        ConfigOption('mount_point', str, 'app'),
...
...
176
    AttachmentClass = model.DiscussionAttachment
179
    AttachmentClass = model.DiscussionAttachment
177
    tool_label='Tool'
180
    tool_label='Tool'
178
    tool_description="This is a tool for Allura forge."
181
    tool_description="This is a tool for Allura forge."
179
    default_mount_label='Tool Name'
182
    default_mount_label='Tool Name'
180
    default_mount_point='tool'
183
    default_mount_point='tool'
184
    relaxed_mount_points=False
181
    ordinal=0
185
    ordinal=0
182
    hidden = False
186
    hidden = False
183
    icons={
187
    icons={
184
        24:'images/admin_24.png',
188
        24:'images/admin_24.png',
185
        32:'images/admin_32.png',
189
        32:'images/admin_32.png',
...
...
199
    def acl(self):
203
    def acl(self):
200
        return self.config.acl
204
        return self.config.acl
201
205
202
    def parent_security_context(self):
206
    def parent_security_context(self):
203
        return self.config.parent_security_context()
207
        return self.config.parent_security_context()
208
209
    @classmethod
210
    def validate_mount_point(cls, mount_point):
211
        """Check if ``mount_point`` is valid for this Application.
212
213
        In general, subclasses should not override this, but rather toggle
214
        the strictness of allowed mount point names by toggling
215
        :attr:`Application.relaxed_mount_points`.
216
217
        :param mount_point: the mount point to validate
218
        :type mount_point: str
219
        :rtype: A :class:`regex Match object <_sre.SRE_Match>` if the mount
220
                point is valid, else None
221
222
        """
223
        re = (h.re_relaxed_tool_mount_point if cls.relaxed_mount_points
224
                else h.re_tool_mount_point)
225
        return re.match(mount_point)
204
226
205
    @classmethod
227
    @classmethod
206
    def status_int(self):
228
    def status_int(self):
207
        return self.status_map.index(self.status)
229
        return self.status_map.index(self.status)
208
230
...
...
448
            allow_config=has_access(self.app, 'configure')())
470
            allow_config=has_access(self.app, 'configure')())
449
471
450
    @expose()
472
    @expose()
451
    @require_post()
473
    @require_post()
452
    def configure(self, **kw):
474
    def configure(self, **kw):
453
        with push_config(c, app=self.app):
475
        with h.push_config(c, app=self.app):
454
            require_access(self.app, 'configure')
476
            require_access(self.app, 'configure')
455
            is_admin = self.app.config.tool_name == 'admin'
477
            is_admin = self.app.config.tool_name == 'admin'
456
            if kw.pop('delete', False):
478
            if kw.pop('delete', False):
457
                if is_admin:
479
                if is_admin:
458
                    flash('Cannot delete the admin tool, sorry....')
480
                    flash('Cannot delete the admin tool, sorry....')
...
...
479
            else:
501
            else:
480
                redirect(request.referer)
502
                redirect(request.referer)
481
503
482
    @without_trailing_slash
504
    @without_trailing_slash
483
    @expose()
505
    @expose()
484
    @vardec
506
    @h.vardec
485
    @require_post()
507
    @require_post()
486
    def update(self, card=None, **kw):
508
    def update(self, card=None, **kw):
487
        self.app.config.acl = []
509
        self.app.config.acl = []
488
        for args in card:
510
        for args in card:
489
            perm = args['id']
511
            perm = args['id']