Indefero

Indefero Commit Details


Date:2008-11-21 06:19:02 (16 years 1 month ago)
Author:Loic d'Anterroches
Branch:dev, develop, feature-issue_links, feature.better-home, feature.content-md5, feature.diff-whitespace, feature.download-md5, feature.issue-links, feature.issue-of-others, feature.issue-summary, feature.search-filter, feature.webrepos, feature.wiki-default-page, master, release-1.1, release-1.2, release-1.3
Commit:0e725bea26b9a543f66fa201eecf1666e9e7a598
Parents: 80b9e2ff78ef04acf5861c3f9e8a02c632e0dd5f
Message:Added private projects.

It is now possible to create private projects. To mark a project as
private, you simply go in the Administer > Tabs Access menu and select
"Private project". Only project members and owners together with the
extra authorized users will be able to access the project. The project
will not appear in the list of projects for not authorized users.
Changes:

File differences

src/IDF/Form/TabsConf.php
2828
2929
3030
31
32
3133
3234
3335
36
37
3438
3539
3640
......
5155
5256
5357
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
54108
55109
56110
57111
112
class IDF_Form_TabsConf extends Pluf_Form
{
public $conf = null;
public $project = null;
public function initFields($extra=array())
{
$this->conf = $extra['conf'];
$this->project = $extra['project'];
$ak = array('downloads_access_rights' => __('Downloads'),
'source_access_rights' => __('Source'),
'issues_access_rights' => __('Issues'),);
'widget' => 'Pluf_Form_Widget_SelectInput',
));
}
$this->fields['private_project'] = new Pluf_Form_Field_Boolean(
array('required' => false,
'label' => __('Private project'),
'initial' => $this->project->private,
'widget' => 'Pluf_Form_Widget_CheckboxInput',
));
$this->fields['authorized_users'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Extra authorized users'),
'widget_attrs' => array('rows' => 7,
'cols' => 40),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
}
public function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
// remove all the permissions
$perm = Pluf_Permission::getFromString('IDF.project-authorized-user');
if ($perm == false) {
// We do not have this perm for the moment in the system,
// so create it.
$perm = new Pluf_Permission();
$perm->name = 'Project authorized users';
$perm->code_name = 'project-authorized-user';
$perm->description = 'Permission given to users allowed to access a project.';
$perm->application = 'IDF';
$perm->create();
}
$cm = $this->project->getMembershipData();
$guser = new Pluf_User();
foreach ($cm['authorized'] as $user) {
Pluf_RowPermission::remove($user, $this->project, $perm);
}
if ($this->cleaned_data['private_project']) {
foreach (preg_split("/\015\012|\015|\012|\,/", $this->cleaned_data['authorized_users'], -1, PREG_SPLIT_NO_EMPTY) as $login) {
$sql = new Pluf_SQL('login=%s', array(trim($login)));
$users = $guser->getList(array('filter'=>$sql->gen()));
if ($users->count() == 1) {
Pluf_RowPermission::add($users[0], $this->project, $perm);
}
}
$this->project->private = 1;
} else {
$this->project->private = 0;
}
$this->project->update();
}
}
src/IDF/Migrations/6PrivateProject.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 CĂ©ondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Add the private column for the project.
*/
function IDF_Migrations_6PrivateProject_up($params=null)
{
$table = Pluf::factory('IDF_Project')->getSqlTable();
$sql = array();
$sql['PostgreSQL'] = 'ALTER TABLE '.$table.' ADD COLUMN "private" INTEGER DEFAULT 0';
$sql['MySQL'] = 'ALTER TABLE '.$table.' ADD COLUMN `private` INTEGER DEFAULT 0';
$db = Pluf::db();
$engine = Pluf::f('db_engine');
if (!isset($sql[$engine])) {
throw new Exception('SQLite complex migration not supported.');
}
$db->execute($sql[$engine]);
}
function IDF_Migrations_6PrivateProject_down($params=null)
{
$table = Pluf::factory('IDF_Project')->getSqlTable();
$sql = array();
$sql['PostgreSQL'] = 'ALTER TABLE '.$table.' DROP COLUMN "private"';
$sql['MySQL'] = 'ALTER TABLE '.$table.' DROP COLUMN `private`';
$db = Pluf::db();
$engine = Pluf::f('db_engine');
if (!isset($sql[$engine])) {
throw new Exception('SQLite complex migration not supported.');
}
$db->execute($sql[$engine]);
}
src/IDF/Migrations/Install.php
3838
3939
4040
41
4142
4243
4344
......
6768
6869
6970
71
72
7073
7174
7275
'IDF_Upload',
'IDF_Search_Occ',
'IDF_IssueFile',
'IDF_Timeline',
);
$db = Pluf::db();
$schema = new Pluf_DB_Schema($db);
$perm = Pluf_Permission::getFromString('IDF.project-owner');
if ($perm) $perm->delete();
$models = array(
'IDF_Timeline',
'IDF_IssueFile',
'IDF_Search_Occ',
'IDF_Upload',
'IDF_Conf',
src/IDF/Precondition.php
2424
2525
2626
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2747
2848
2949
......
98118
99119
100120
121
122
123
124
101125
102126
103127
104128
105129
130
131
132
133
106134
107135
108136
109137
110138
139
140
141
142
111143
112144
113145
class IDF_Precondition
{
/**
* Check if the user has a base authorization to access a given
* tab. This used in the case of private project. You need to
* further control with the accessSource, accessIssues,
* etc. preconditions.
*
* @param Pluf_HTTP_Request
* @return mixed
*/
static public function baseAccess($request)
{
if (!$request->project->private) {
return true;
}
if ($request->user->hasPerm('IDF.project-authorized-user', $request->project)) {
return true;
}
return self::projectMemberOrOwner($request);
}
/**
* Check if the user is project owner.
*
* @param Pluf_HTTP_Request
static public function accessSource($request)
{
$res = self::baseAccess($request);
if (true !== $res) {
return $res;
}
return self::accessTabGeneric($request, 'source_access_rights');
}
static public function accessIssues($request)
{
$res = self::baseAccess($request);
if (true !== $res) {
return $res;
}
return self::accessTabGeneric($request, 'issues_access_rights');
}
static public function accessDownloads($request)
{
$res = self::baseAccess($request);
if (true !== $res) {
return $res;
}
return self::accessTabGeneric($request, 'downloads_access_rights');
}
}
src/IDF/Project.php
7070
7171
7272
73
74
75
76
77
78
79
7380
74
7581
7682
7783
......
214220
215221
216222
217
223
218224
219225
220226
......
228234
229235
230236
237
231238
232239
233240
......
251258
252259
253260
261
262
263
264
265
266
267
268
269
270
271
272
254273
255
274
256275
257276
258
277
278
279
259280
260281
261282
'verbose' => __('description'),
'help_text' => __('The description can be extended using the markdown syntax.'),
),
'private' =>
array(
'type' => 'Pluf_DB_Field_Integer',
'blank' => false,
'verbose' => __('private'),
'default' => 0,
),
);
$this->_a['idx'] = array( );
}
/**
* Return membership data.
*
* The array has 2 keys: 'members' and 'owners'.
* The array has 3 keys: 'members', 'owners' and 'authorized'.
*
* The list of users is only taken using the row level permission
* table. That is, if you set a user as administrator, he will
{
$mperm = Pluf_Permission::getFromString('IDF.project-member');
$operm = Pluf_Permission::getFromString('IDF.project-owner');
$aperm = Pluf_Permission::getFromString('IDF.project-authorized-user');
$grow = new Pluf_RowPermission();
$db =& Pluf::db();
$false = Pluf_DB_BooleanToDb(false, $db);
$members[] = Pluf::factory('Pluf_User', $row->owner_id)->login;
}
}
$authorized = new Pluf_Template_ContextVars(array());
if ($aperm != false) {
$sql = new Pluf_SQL('model_class=%s AND model_id=%s AND owner_class=%s AND permission=%s AND negative='.$false,
array('IDF_Project', $this->id, 'Pluf_User', $aperm->id));
foreach ($grow->getList(array('filter' => $sql->gen())) as $row) {
if ($fmt == 'objects') {
$authorized[] = Pluf::factory('Pluf_User', $row->owner_id);
} else {
$authorized[] = Pluf::factory('Pluf_User', $row->owner_id)->login;
}
}
}
if ($fmt == 'objects') {
return new Pluf_Template_ContextVars(array('members' => $members, 'owners' => $owners));
return new Pluf_Template_ContextVars(array('members' => $members, 'owners' => $owners, 'authorized' => $authorized));
} else {
return array('members' => implode("\n", (array) $members),
'owners' => implode("\n", (array) $owners));
'owners' => implode("\n", (array) $owners),
'authorized' => implode("\n", (array) $authorized),
);
}
}
src/IDF/Views.php
3333
3434
3535
36
37
38
3639
3740
3841
39
42
4043
4144
4245
......
171174
172175
173176
174
177
175178
176179
177180
......
180183
181184
182185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
183224
{
/**
* List all the projects managed by InDefero.
*
* Only the public projects are listed or the private with correct
* rights.
*/
public function index($request, $match)
{
$projects = Pluf::factory('IDF_Project')->getList();
$projects = self::getProjects($request->user);
return Pluf_Shortcuts_RenderToResponse('idf/index.html',
array('page_title' => __('Projects'),
'projects' => $projects),
public function faq($request, $match)
{
$title = __('Here to Help You!');
$projects = Pluf::factory('IDF_Project')->getList();
$projects = self::getProjects($request->user);
return Pluf_Shortcuts_RenderToResponse('idf/faq.html',
array(
'page_title' => $title,
$request);
}
/**
* Returns a list of projects accessible for the user.
*
* @param Pluf_User
* @return ArrayObject IDF_Project
*/
public static function getProjects($user)
{
$db =& Pluf::db();
$false = Pluf_DB_BooleanToDb(false, $db);
if ($user->isAnonymous()) {
$sql = sprintf('%s=%s', $db->qn('private'), $false);
return Pluf::factory('IDF_Project')->getList(array('filter'=> $sql));
}
if ($user->administrator) {
return Pluf::factory('IDF_Project')->getList();
}
// grab the list of projects where the user is admin, member
// or authorized
$perms = array(
Pluf_Permission::getFromString('IDF.project-member'),
Pluf_Permission::getFromString('IDF.project-owner'),
Pluf_Permission::getFromString('IDF.project-authorized-user')
);
$sql = new Pluf_SQL("model_class='IDF_Project' AND owner_class='Pluf_User' AND owner_id=%s AND negative=".$false, $user->id);
$rows = Pluf::factory('Pluf_RowPermission')->getList(array('filter' => $sql->gen()));
$sql = sprintf('%s=%s', $db->qn('private'), $false);
if ($rows->count() > 0) {
$ids = array();
foreach ($rows as $row) {
$ids[] = $row->model_id;
}
$sql .= sprintf(' OR id IN (%s)', implode(', ', $ids));
}
return Pluf::factory('IDF_Project')->getList(array('filter' => $sql));
}
}
src/IDF/Views/Project.php
3434
3535
3636
37
3738
3839
3940
......
5758
5859
5960
61
6062
6163
6264
......
272274
273275
274276
277
275278
276279
277280
......
280283
281284
282285
286
283287
284288
285289
......
288292
289293
290294
291
295
292296
293297
294298
295299
296300
297301
302
303
304
298305
299306
300307
/**
* Home page of a project.
*/
public $home_precond = array('IDF_Precondition::baseAccess');
public function home($request, $match)
{
$prj = $request->project;
/**
* Timeline of the project.
*/
public $timeline_precond = array('IDF_Precondition::baseAccess');
public function timeline($request, $match)
{
$prj = $request->project;
$prj = $request->project;
$title = sprintf(__('%s Tabs Access Rights'), (string) $prj);
$extra = array(
'project' => $prj,
'conf' => $request->conf,
);
if ($request->method == 'POST') {
foreach ($form->cleaned_data as $key=>$val) {
$request->conf->setVal($key, $val);
}
$form->save(); // Save the authorized users.
$request->user->setMessage(__('The project tabs access rights have been saved.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminTabs',
array($prj->shortname));
} else {
$params = array();
$keys = array('downloads_access_rights', 'source_access_rights',
'issues_access_rights');
'issues_access_rights', 'private_project');
foreach ($keys as $key) {
$_val = $request->conf->getVal($key, false);
if ($_val !== false) {
$params[$key] = $_val;
}
}
// Add the authorized users.
$md = $prj->getMembershipData('string');
$params['authorized_users'] = $md['authorized'];
if (count($params) == 0) {
$params = null; //Nothing in the db, so new form.
}
src/IDF/conf/idf.php-dist
122122
123123
124124
125
126
127
128
129
130
125131
126132
127
133
128134
129135
130136
$cfg['db_server'] = '';
$cfg['db_version'] = '';
$cfg['db_table_prefix'] = '';
// ** DO NOT USE SQLITE IN PRODUCTION **
// This is not because of problems with the quality of the SQLite
// driver or with SQLite itself, this is due to the lack of migration
// support in Pluf for SQLite, this means we cannot modify the DB
// easily once it is loaded with data.
$cfg['db_engine'] = 'PostgreSQL'; // SQLite is also well tested or MySQL
$cfg['db_database'] = 'website'; // put absolute path to the db if you
// are using SQLite
// are using SQLite.
// -- From this point you should not need to update anything. --
$cfg['pear_path'] = '/usr/share/php';
src/IDF/templates/idf/admin/tabs.html
11
2
2
33
44
55
......
3030
3131
3232
33
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
3448
3549
3650
......
4155
4256
4357
58
59
4460
4561
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{extends "idf/admin/base.html"}
{block docclass}yui-t1{assign $inTabs = true}{/block}
{block docclass}yui-t3{assign $inTabs = true}{/block}
{block body}
{if $form.errors}
<div class="px-message-error">
</td>
</tr>
<tr>
<td colspan="2">
<th>{if $form.f.private_project.errors}{$form.f.private_project.fieldErrors}{/if}
{$form.f.private_project|unsafe}
</th>
<td>{$form.f.private_project.labelTag}</td>
</tr>
<tr id="authorized-users-row">
<td>&nbsp;</td>
<td>{$form.f.authorized_users.labelTag}:<br />
{if $form.f.authorized_users.errors}{$form.f.authorized_users.fieldErrors}{/if}
{$form.f.authorized_users|unsafe}
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input type="submit" value="{trans 'Save Changes'}" name="submit" />
</td>
</tr>
<div class="issue-submit-info">
<p><strong>{trans 'Instructions:'}</strong></p>
<p>{blocktrans}You can configure here the project tabs access rights.{/blocktrans}</p>
<p>{blocktrans}If you mark a project as private, only the project members and administrators, together with the extra authorized users you provide will have access to the project. You will still be able to define further access rights for the different tabs but the "Open to all" and "Signed in users" will default to authorized users only.{/blocktrans}</p>
<p>{blocktrans}Specify each person by its login. Each person must have already registered with the given login. Separate the logins with commas and/or new lines.{/blocktrans}</p>
</div>
{/block}
{block javascript}{literal}
<script type="text/javascript">
$(document).ready(function(){
// If not checked, hide
if (!$("#id_private_project").is(":checked"))
$("#authorized-users-row").hide();
$("#id_private_project").click(function(){
if ($("#id_private_project").is(":checked")) {
$("#authorized-users-row").show();
} else {
$("#authorized-users-row").hide();
}
});
});
</script>
{/literal}{/block}

Archive Download the corresponding diff file

Page rendered in 0.11415s using 13 queries.