Merge lp:~benoit.pierre/sloecode/public-projects into lp:sloecode

Proposed by Benoit Pierre
Status: Merged
Merged at revision: 135
Proposed branch: lp:~benoit.pierre/sloecode/public-projects
Merge into: lp:sloecode
Diff against target: 313 lines (+112/-10)
13 files modified
dbpatches/patches/mysql/3 (+9/-0)
dbpatches/patches/sqlite3/3 (+9/-0)
help_pages/what-is/repo-type.rst (+5/-3)
sloecode/controllers/admin/project.py (+2/-0)
sloecode/controllers/xmlrpc.py (+7/-0)
sloecode/lib/helpers.py (+3/-1)
sloecode/lib/predicates.py (+1/-1)
sloecode/lib/security.py (+48/-0)
sloecode/model/project.py (+9/-1)
sloecode/templates/admin/project-create.html (+8/-0)
sloecode/templates/admin/project-list.html (+2/-0)
sloecode/templates/admin/project-update.html (+4/-0)
sloecode/templates/macros/nav.html (+5/-4)
To merge this branch: bzr merge lp:~benoit.pierre/sloecode/public-projects
Reviewer Review Type Date Requested Status
sloecode Pending
Review via email: mp+80268@code.launchpad.net

Description of the change

Add support for public projects. A public project will be accessible (read-only) by all users.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'dbpatches/patches/mysql/3'
2--- dbpatches/patches/mysql/3 1970-01-01 00:00:00 +0000
3+++ dbpatches/patches/mysql/3 2011-10-24 20:51:24 +0000
4@@ -0,0 +1,9 @@
5+/*
6+This patch add the public column to the projects table, defaulting all projects to private.
7+*/
8+
9+-- add public column:
10+ALTER TABLE project ADD public BOOLEAN CHECK (public IN (0, 1));
11+
12+- default to private:
13+UPDATE project SET public=0;
14
15=== added file 'dbpatches/patches/sqlite3/3'
16--- dbpatches/patches/sqlite3/3 1970-01-01 00:00:00 +0000
17+++ dbpatches/patches/sqlite3/3 2011-10-24 20:51:24 +0000
18@@ -0,0 +1,9 @@
19+/*
20+This patch add the public column to the projects table, defaulting all projects to private.
21+*/
22+
23+-- add public column:
24+ALTER TABLE project ADD public BOOLEAN CHECK (public IN (0, 1));
25+
26+- default to private:
27+UPDATE project SET public=0;
28
29=== modified file 'help_pages/what-is/repo-type.rst'
30--- help_pages/what-is/repo-type.rst 2011-04-03 02:03:16 +0000
31+++ help_pages/what-is/repo-type.rst 2011-10-24 20:51:24 +0000
32@@ -5,9 +5,11 @@
33
34 * *Project Repositories* provide a shared development space for several
35 developers all working on a common project. Your access to a project
36- repository is controlled by your membership type in that project (Project
37- observers have read-only access, developers and managers have read/write
38- access).
39+ repository is controlled by your membership type in that project:
40+ - project observers have read-only access
41+ - developers and managers have read/write access
42+
43+ Additionally, public projects are accessible (read-only) to all users.
44
45 Assuming you have the bzr-sloecode plugin installed, you can access a
46 project repository with the following URI::
47
48=== modified file 'sloecode/controllers/admin/project.py'
49--- sloecode/controllers/admin/project.py 2011-06-22 06:54:54 +0000
50+++ sloecode/controllers/admin/project.py 2011-10-24 20:51:24 +0000
51@@ -53,6 +53,7 @@
52 new_project.name = form_result['name']
53 new_project.displayname = form_result['displayname']
54 new_project.description = form_result['description']
55+ new_project.public = form_result['public']
56
57 Session.add(new_project)
58 Session.commit()
59@@ -88,6 +89,7 @@
60 project = Project.get(id=id)[0]
61 project.displayname = form_result['displayname']
62 project.description = form_result['description']
63+ project.public = form_result['public']
64
65 Session.merge(project)
66 Session.commit()
67
68=== modified file 'sloecode/controllers/xmlrpc.py'
69--- sloecode/controllers/xmlrpc.py 2011-03-25 08:45:06 +0000
70+++ sloecode/controllers/xmlrpc.py 2011-10-24 20:51:24 +0000
71@@ -5,6 +5,7 @@
72
73 from pylons.controllers.xmlrpc import XMLRPCController
74 from sloecode.model import Person, Project
75+from sloecode.model.project import public_projects
76 from sloecode.model.site_role import PROJECT_ADMIN
77 from sloecode.model.membership import PR_DEVELOPER, PR_MANAGER
78
79@@ -79,6 +80,12 @@
80 writable_projects.append(mem.project.name)
81 else:
82 readable_projects.append(mem.project.name)
83+ for project in public_projects():
84+ if project.name in writable_projects:
85+ continue
86+ if project.name in readable_projects:
87+ continue
88+ readable_projects.append(project.name)
89 return [isAdmin, readable_projects, writable_projects]
90
91 getAccessPermissionsForUser.signature = [['array', 'string']]
92
93=== modified file 'sloecode/lib/helpers.py'
94--- sloecode/lib/helpers.py 2011-10-01 14:35:25 +0000
95+++ sloecode/lib/helpers.py 2011-10-24 20:51:24 +0000
96@@ -23,6 +23,7 @@
97 # Roles information
98 from sloecode.model.membership import PROJECT_ROLES
99 from sloecode.model.site_role import SITE_ROLES
100+from sloecode.model.project import public_projects
101
102 # a simple link_to implementation that handles a confirm kwarg that prints
103 # very simple javascript asking the user if they really want to continue.
104@@ -56,7 +57,8 @@
105
106 # import helper functions that let templates determine if the user has
107 # certain permissions:
108-from sloecode.lib.security import has_site_role, has_project_role, has_project_access
109+from sloecode.lib.security import (has_site_role, has_project_role,
110+ has_project_access, visible_projects)
111 # import site role names as well:
112 from sloecode.model.site_role import USER_ADMIN, PROJECT_ADMIN
113
114
115=== modified file 'sloecode/lib/predicates.py'
116--- sloecode/lib/predicates.py 2011-10-01 14:35:25 +0000
117+++ sloecode/lib/predicates.py 2011-10-24 20:51:24 +0000
118@@ -63,7 +63,7 @@
119 being requested.
120 """
121
122- message = "You must be a member of a project in order to view it's page."
123+ message = "You must be a member of a project or it must be public in order to view it's page."
124
125 def evaluate(self, environ, credentials):
126 try:
127
128=== modified file 'sloecode/lib/security.py'
129--- sloecode/lib/security.py 2011-10-01 14:35:25 +0000
130+++ sloecode/lib/security.py 2011-10-24 20:51:24 +0000
131@@ -5,6 +5,8 @@
132 from pylons import request
133 from sloecode.model import Person, Membership, Project
134 from sloecode.model.meta import Session
135+from sloecode.model.project import public_projects
136+from sloecode.model.site_role import PROJECT_ADMIN
137 from sloecode.model.membership import PR_MANAGER, PR_DEVELOPER
138
139
140@@ -75,6 +77,9 @@
141 prj_obj = _get_project_object(project)
142 if prj_obj is None:
143 return False
144+ if read_only and prj_obj.public:
145+ # Read only access allowed for everybody if project is public.
146+ return True
147 try:
148 if not user:
149 e = request.environ
150@@ -92,3 +97,46 @@
151 return False
152 return False
153
154+def _get_user_object(user):
155+ usr_obj = None
156+ if isinstance(user, Person):
157+ usr_obj = user
158+ elif isinstance(user, int):
159+ users = Person.get(id=user)
160+ if len(users):
161+ usr_obj = users[0]
162+ else:
163+ # that ID does not exist.
164+ return None
165+ elif isinstance(user, basestring):
166+ users = Person.get(name=user)
167+ if len(users):
168+ usr_obj = users[0]
169+ else:
170+ # that name does not exist.
171+ return None
172+ else:
173+ raise TypeError("user must be Person,str,unicode, or int type.")
174+ return usr_obj
175+
176+def visible_projects(user):
177+ """Get the list of projects visible by a user.
178+
179+ For an admin user, return all projects.
180+
181+ For a normal user, returns a list containing:
182+ - the projects the user is a member of
183+ - and the public projects
184+
185+ """
186+ usr_obj = _get_user_object(user)
187+ is_admin = PROJECT_ADMIN in [sr.role for sr in usr_obj.site_roles]
188+ if is_admin:
189+ return Project.get()
190+ projects = []
191+ for membership in usr_obj.projects:
192+ projects.append(membership.project)
193+ projects.extend(public_projects())
194+ projects = list(set(projects))
195+ return projects
196+
197
198=== modified file 'sloecode/model/project.py'
199--- sloecode/model/project.py 2011-09-30 23:41:48 +0000
200+++ sloecode/model/project.py 2011-10-24 20:51:24 +0000
201@@ -6,7 +6,7 @@
202
203 from sqlalchemy import Column
204 from sqlalchemy.orm import relationship
205-from sqlalchemy.types import Integer, String, Text
206+from sqlalchemy.types import Boolean, Integer, String, Text
207
208
209 from sloecode.model.meta import Base, QueryMixin
210@@ -22,6 +22,7 @@
211
212 id = Column(Integer, primary_key=True)
213 name = Column(String(24), unique=True)
214+ public = Column(Boolean)
215 displayname = Column(String(32))
216 description = Column(Text())
217
218@@ -57,5 +58,12 @@
219 filter_extra_fields = True
220
221 name = UniqueProject(not_empty=True)
222+ public = formencode.validators.Bool()
223 displayname = formencode.validators.String(not_empty=True, max=32)
224 description = formencode.validators.String(not_empty=False)
225+
226+
227+def public_projects():
228+ """ Return the list of public projects. """
229+ return Project.get(public=True)
230+
231
232=== modified file 'sloecode/templates/admin/project-create.html'
233--- sloecode/templates/admin/project-create.html 2011-06-22 06:54:54 +0000
234+++ sloecode/templates/admin/project-create.html 2011-10-24 20:51:24 +0000
235@@ -37,6 +37,14 @@
236 <td>{{ mt.textarea('description', cols=45, rows=5) }}</td>
237 </tr>
238 <tr>
239+ <td>Public<br />
240+ <span class="entry-hint">If public, all users, even non-members, will have read-access.</span>
241+ </td>
242+ <td>
243+ {{mt.checkbox('public')}}
244+ </td>
245+ </tr>
246+ <tr>
247 <td colspan="2">
248 {{h.submit('update', 'Create Project')}}
249 </td>
250
251=== modified file 'sloecode/templates/admin/project-list.html'
252--- sloecode/templates/admin/project-list.html 2011-10-01 14:01:17 +0000
253+++ sloecode/templates/admin/project-list.html 2011-10-24 20:51:24 +0000
254@@ -21,6 +21,7 @@
255 <th>Name</th>
256 <th>Display Name</th>
257 <th>Description</th>
258+ <th>Public</th>
259 <th>Actions</th>
260 </tr>
261 {% set row_class = cycler('odd', 'even') %}
262@@ -31,6 +32,7 @@
263 class='project') }}</td>
264 <td>{{project.displayname|e}}</td>
265 <td>{{project.description|e}}</td>
266+ <td>{% if project.public %}Yes{% else %}No{% endif %}</td>
267 <td>{{h.link_to('Edit',
268 h.url(controller='admin/project',
269 action='update',
270
271=== modified file 'sloecode/templates/admin/project-update.html'
272--- sloecode/templates/admin/project-update.html 2011-06-22 06:54:54 +0000
273+++ sloecode/templates/admin/project-update.html 2011-10-24 20:51:24 +0000
274@@ -18,6 +18,10 @@
275 <td>{{ mt.textarea('description') }}</td>
276 </tr>
277 <tr>
278+ <td>Public</td>
279+ <td>{{ mt.checkbox('public') }}</td>
280+ </tr>
281+ <tr>
282 <td colspan="2">
283 {{h.submit('update', 'Update Project')}}
284 </td>
285
286=== modified file 'sloecode/templates/macros/nav.html'
287--- sloecode/templates/macros/nav.html 2011-10-01 14:01:17 +0000
288+++ sloecode/templates/macros/nav.html 2011-10-24 20:51:24 +0000
289@@ -31,7 +31,8 @@
290 class='yui3-menuitem-content') }}
291 </li>
292
293- {% if user_details.projects|length %}
294+ {% set projects = h.visible_projects(user_details) %}
295+ {% if projects|length %}
296 <li>
297 <a class="yui3-menu-label" href="#proj_list">
298 <em>Projects</em>
299@@ -41,11 +42,11 @@
300 <div class="yui3-menu-content">
301 <ul>
302 {# List of projects that this user is in #}
303- {% for membership in user_details.projects|attrsort('project.name') %}
304+ {% for project in projects|attrsort('name') %}
305 <li class="yui3-menuitem">
306- {{ h.link_to(membership.project.name,
307+ {{ h.link_to(project.name,
308 h.url(controller='project',
309- project_name=membership.project.name),
310+ project_name=project.name),
311 class='yui3-menuitem-content'
312 ) }}
313 </li>

Subscribers

People subscribed via source and target branches