Switch to unified view

a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
...
...
23
from allura.lib.base import WsgiDispatchController
23
from allura.lib.base import WsgiDispatchController
24
from allura.lib import helpers as h
24
from allura.lib import helpers as h
25
from allura.lib import utils
25
from allura.lib import utils
26
from allura.lib.decorators import require_post
26
from allura.lib.decorators import require_post
27
from allura.controllers.error import ErrorController
27
from allura.controllers.error import ErrorController
28
from allura.lib.security import require, has_project_access, has_neighborhood_access
28
from allura.lib.security import require_access, has_access
29
from allura.lib.security import RoleCache
29
from allura.lib.security import RoleCache
30
from allura.lib.widgets import form_fields as ffw
30
from allura.lib.widgets import form_fields as ffw
31
from allura.lib.widgets import forms as forms
31
from allura.lib.widgets import forms as forms
32
from allura.lib.widgets import project_list as plw
32
from allura.lib.widgets import project_list as plw
33
from allura.lib import plugin
33
from allura.lib import plugin
...
...
58
        self.browse = NeighborhoodProjectBrowseController(neighborhood=self.neighborhood)
58
        self.browse = NeighborhoodProjectBrowseController(neighborhood=self.neighborhood)
59
        self._admin = NeighborhoodAdminController(self.neighborhood)
59
        self._admin = NeighborhoodAdminController(self.neighborhood)
60
        self._moderate = NeighborhoodModerateController(self.neighborhood)
60
        self._moderate = NeighborhoodModerateController(self.neighborhood)
61
61
62
    def _check_security(self):
62
    def _check_security(self):
63
        require(has_neighborhood_access('read', self.neighborhood),
63
        require_access(self.neighborhood, 'read')
64
                'Read access required')
65
64
66
    @expose()
65
    @expose()
67
    def _lookup(self, pname, *remainder):
66
    def _lookup(self, pname, *remainder):
68
        pname = unquote(pname)
67
        pname = unquote(pname)
69
        if not h.re_path_portion.match(pname):
68
        if not h.re_path_portion.match(pname):
...
...
71
        project = M.Project.query.get(shortname=self.prefix + pname)
70
        project = M.Project.query.get(shortname=self.prefix + pname)
72
        if project is None:
71
        if project is None:
73
            project = M.Project.query.get(
72
            project = M.Project.query.get(
74
                shortname='--init--',
73
                shortname='--init--',
75
                neighborhood_id=self.neighborhood._id)
74
                neighborhood_id=self.neighborhood._id)
76
            if not project:
77
                # Go ahead and register it
78
                project_reg = plugin.ProjectRegistrationProvider.get()
79
                users = M.User.query.find(dict(_id={'$in':self.neighborhood.acl.admin})).all()
80
                project = project_reg.register_neighborhood_project(self.neighborhood, users)
81
            if project:
82
                c.project = project
75
            c.project = project
83
                return ProjectController()._lookup(pname, *remainder)
76
            return ProjectController()._lookup(pname, *remainder)
84
        if project.database_configured == False:
77
        if project.database_configured == False:
85
            if remainder == ('user_icon',):
78
            if remainder == ('user_icon',):
86
                redirect(g.forge_static('images/user.png'))
79
                redirect(g.forge_static('images/user.png'))
87
            elif c.user.username == pname:
80
            elif c.user.username == pname:
88
                log.info('Configuring %s database for access to %r',
81
                log.info('Configuring %s database for access to %r',
89
                         pname, remainder)
82
                         pname, remainder)
90
                project.configure_project(is_user_project=True)
83
                project.configure_project(is_user_project=True)
91
            else:
84
            else:
92
                raise exc.HTTPNotFound, pname
85
                raise exc.HTTPNotFound, pname
93
        c.project = project
86
        c.project = project
94
        if project is None or (project.deleted and not has_project_access('update')()):
87
        if project is None or (project.deleted and not has_access(c.project, 'update')()):
95
            raise exc.HTTPNotFound, pname
88
            raise exc.HTTPNotFound, pname
96
        if project.neighborhood.name != self.neighborhood_name:
89
        if project.neighborhood.name != self.neighborhood_name:
97
            redirect(project.url())
90
            redirect(project.url())
98
        return ProjectController(), remainder
91
        return ProjectController(), remainder
99
92
...
...
134
                    limit=limit, page=page, count=count)
127
                    limit=limit, page=page, count=count)
135
128
136
    @expose('jinja:allura:templates/neighborhood_add_project.html')
129
    @expose('jinja:allura:templates/neighborhood_add_project.html')
137
    @without_trailing_slash
130
    @without_trailing_slash
138
    def add_project(self, **form_data):
131
    def add_project(self, **form_data):
139
        require(has_neighborhood_access('create', self.neighborhood), 'Create access required')
132
        require_access(self.neighborhood, 'create')
140
        c.add_project = W.add_project
133
        c.add_project = W.add_project
141
        for checkbox in ['Wiki','Git','Tickets','Downloads','Discussion']:
134
        for checkbox in ['Wiki','Git','Tickets','Downloads','Discussion']:
142
            form_data.setdefault(checkbox, True)
135
            form_data.setdefault(checkbox, True)
143
        form_data['neighborhood'] = self.neighborhood.name
136
        form_data['neighborhood'] = self.neighborhood.name
144
        return dict(neighborhood=self.neighborhood, form_data=form_data)
137
        return dict(neighborhood=self.neighborhood, form_data=form_data)
...
...
162
    @expose()
155
    @expose()
163
    @validate(W.add_project, error_handler=add_project)
156
    @validate(W.add_project, error_handler=add_project)
164
    @utils.AntiSpam.validate('Spambot protection engaged')
157
    @utils.AntiSpam.validate('Spambot protection engaged')
165
    @require_post()
158
    @require_post()
166
    def register(self, project_unixname=None, project_description=None, project_name=None, neighborhood=None, **kw):
159
    def register(self, project_unixname=None, project_description=None, project_name=None, neighborhood=None, **kw):
167
        require(has_neighborhood_access('create', self.neighborhood), 'Create access required')
160
        require_access(self.neighborhood, 'create')
168
        project_description = h.really_unicode(project_description or '').encode('utf-8')
161
        project_description = h.really_unicode(project_description or '').encode('utf-8')
169
        project_name = h.really_unicode(project_name or '').encode('utf-8')
162
        project_name = h.really_unicode(project_name or '').encode('utf-8')
170
        project_unixname = h.really_unicode(project_unixname or '').encode('utf-8').lower()
163
        project_unixname = h.really_unicode(project_unixname or '').encode('utf-8').lower()
171
        neighborhood = M.Neighborhood.query.get(name=neighborhood)
164
        neighborhood = M.Neighborhood.query.get(name=neighborhood)
172
        c.project = neighborhood.register_project(project_unixname)
165
        c.project = neighborhood.register_project(project_unixname)
173
        if project_name:
166
        if project_name:
174
            c.project.name = project_name
167
            c.project.name = project_name
175
        if project_description:
168
        if project_description:
176
            c.project.short_description = project_description
169
            c.project.short_description = project_description
177
        ming.orm.ormsession.ThreadLocalORMSession.flush_all()
170
        ming.orm.ormsession.ThreadLocalORMSession.flush_all()
178
        # require(has_project_access('tool'))
179
        for i, tool in enumerate(kw):
171
        for i, tool in enumerate(kw):
180
            if kw[tool]:
172
            if kw[tool]:
181
                c.project.install_app(tool, ordinal=i)
173
                c.project.install_app(tool, ordinal=i)
182
        flash('Welcome to the SourceForge Beta System! '
174
        flash('Welcome to the SourceForge Beta System! '
183
              'To get started, fill out some information about your project.')
175
              'To get started, fill out some information about your project.')
...
...
257
            raise exc.HTTPNotFound, name
249
            raise exc.HTTPNotFound, name
258
        c.app = app
250
        c.app = app
259
        return app.root, remainder
251
        return app.root, remainder
260
252
261
    def _check_security(self):
253
    def _check_security(self):
262
        require(has_project_access('read'),
254
        require_access(c.project, 'read')
263
                'Read access required')
264
255
265
    @expose()
256
    @expose()
266
    @with_trailing_slash
257
    @with_trailing_slash
267
    def index(self, **kw):
258
    def index(self, **kw):
268
        if c.project.app_instance('home'):
259
        if c.project.app_instance('home'):
...
...
274
265
275
    @expose('jinja:allura:templates/project_sitemap.html')
266
    @expose('jinja:allura:templates/project_sitemap.html')
276
    @without_trailing_slash
267
    @without_trailing_slash
277
    def sitemap(self): # pragma no cover
268
    def sitemap(self): # pragma no cover
278
        raise NotImplementedError, 'sitemap'
269
        raise NotImplementedError, 'sitemap'
279
        require(has_project_access('read'))
280
        return dict()
281
270
282
    @without_trailing_slash
271
    @without_trailing_slash
283
    @expose()
272
    @expose()
284
    @validate(dict(
273
    @validate(dict(
285
            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
274
            since=h.DateTimeConverter(if_empty=None, if_invalid=None),
...
...
386
    def __init__(self, neighborhood):
375
    def __init__(self, neighborhood):
387
        self.neighborhood = neighborhood
376
        self.neighborhood = neighborhood
388
        self.awards = NeighborhoodAwardsController(self.neighborhood)
377
        self.awards = NeighborhoodAwardsController(self.neighborhood)
389
378
390
    def _check_security(self):
379
    def _check_security(self):
391
        require(has_neighborhood_access('admin', self.neighborhood),
380
        require_access(self.neighborhood, 'admin')
392
                'Admin access required')
393
381
394
    def set_nav(self):
382
    def set_nav(self):
395
        project = M.Project.query.find({'shortname':'--init--','neighborhood_id':self.neighborhood._id}).first()
383
        project = M.Project.query.find({'shortname':'--init--','neighborhood_id':self.neighborhood._id}).first()
396
        if project:
384
        if project:
397
            c.project = project
385
            c.project = project
398
            g.set_app('admin')
386
            g.set_app('admin')
399
        else:
387
        else:
400
            admin_url = self.neighborhood.url()+'_admin/'
388
            admin_url = self.neighborhood.url()+'_admin/'
401
            c.custom_sidebar_menu = [
389
            c.custom_sidebar_menu = [
402
                     SitemapEntry('Overview', admin_url+'overview', className='nav_child'),
390
                     SitemapEntry('Overview', admin_url+'overview', className='nav_child'),
403
                     SitemapEntry('Permissions', admin_url+'permissions', className='nav_child'),
404
                     SitemapEntry('Awards', admin_url+'accolades', className='nav_child')]
391
                     SitemapEntry('Awards', admin_url+'accolades', className='nav_child')]
405
392
406
    @with_trailing_slash
393
    @with_trailing_slash
407
    @expose()
394
    @expose()
408
    def index(self, **kw):
395
    def index(self, **kw):
...
...
458
                icon.filename, icon.file, content_type=icon.type,
445
                icon.filename, icon.file, content_type=icon.type,
459
                square=True, thumbnail_size=(48,48),
446
                square=True, thumbnail_size=(48,48),
460
                thumbnail_meta=dict(neighborhood_id=self.neighborhood._id))
447
                thumbnail_meta=dict(neighborhood_id=self.neighborhood._id))
461
        redirect('overview')
448
        redirect('overview')
462
449
463
    @h.vardec
464
    @expose()
465
    @require_post()
466
    def update_acl(self, permission=None, user=None, new=None, **kw):
467
        if user is None: user = []
468
        for u in user:
469
            if u.get('delete'):
470
                if u['id']:
471
                    self.neighborhood.acl[permission].remove(ObjectId(str(u['id'])))
472
                else:
473
                    self.neighborhood.acl[permission].remove(None)
474
        if new.get('add'):
475
            if new['username'] == '*authenticated':
476
                self.neighborhood.acl[permission] = []
477
            elif new['username'] == '*anonymous':
478
                self.neighborhood.acl[permission] = [ None ]
479
            else:
480
                u = M.User.by_username(new['username'])
481
                if u is None:
482
                    flash('Cannot find user "%s"' % new['username'], 'error')
483
                    redirect(request.referer)
484
                else:
485
                    self.neighborhood.acl[permission].append(u._id)
486
        redirect('permissions')
487
488
class NeighborhoodModerateController(object):
450
class NeighborhoodModerateController(object):
489
451
490
    def __init__(self, neighborhood):
452
    def __init__(self, neighborhood):
491
        self.neighborhood = neighborhood
453
        self.neighborhood = neighborhood
492
454
493
    def _check_security(self):
455
    def _check_security(self):
494
        require(has_neighborhood_access('moderate', self.neighborhood),
456
        require_access(self.neighborhood, 'admin')
495
                'Moderator access required')
496
457
497
    @expose('jinja:allura:templates/neighborhood_moderate.html')
458
    @expose('jinja:allura:templates/neighborhood_moderate.html')
498
    def index(self, **kw):
459
    def index(self, **kw):
499
        return dict(neighborhood=self.neighborhood)
460
        return dict(neighborhood=self.neighborhood)
500
461