[opw-web] Centralize permissions / Implement late_submissions / Restrict changing organizations
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [opw-web] Centralize permissions / Implement late_submissions / Restrict changing organizations
- Date: Wed, 19 Mar 2014 14:35:07 +0000 (UTC)
commit d7936ded7fe31ebb3aa72fb95d422e3a20685b0e
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Tue Mar 18 14:16:36 2014 -0400
Centralize permissions / Implement late_submissions / Restrict changing organizations
* Add a central get_project_permissions() call to get the permissions
the user has related to submitting and editing projects.
* Restrict the ability to submit projects between dl_student and dl_mentor
based on organization.late_submission.
* Allow editing of projects between dl_student and dl_mentor.
* Restrict the ability to change organizations - once a organization
is no longer taking submissions, don't allow projects to be moved
to or from that organization.
lang/en-gb.php | 1 +
modules/mod_manage_projects.php | 4 +-
modules/mod_program_home.php | 10 +-
modules/mod_view_projects.php | 163 +++++++-------------
skins/easterngreen/html/tpl_program_home.html | 3 +
.../html/tpl_view_projects_editor.html | 4 +
utils.php | 109 +++++++++++++-
7 files changed, 180 insertions(+), 114 deletions(-)
---
diff --git a/lang/en-gb.php b/lang/en-gb.php
index 5e8dfa3..0363628 100644
--- a/lang/en-gb.php
+++ b/lang/en-gb.php
@@ -130,6 +130,7 @@ $lang_data = array(
'view_submissions' => 'View my submissions',
'create_project' => 'Create new project',
'mentor_project_sel' => 'Select project to mentor',
+ 'late_submission_notice' => 'The general application deadline has passed, however some organizations are
still accepting applications.',
'cancel_mentor' => 'Cancel mentor application',
'view_proposals' => 'View project proposals',
'resign_program' => 'Resign from this program',
diff --git a/modules/mod_manage_projects.php b/modules/mod_manage_projects.php
index caddf28..501f860 100644
--- a/modules/mod_manage_projects.php
+++ b/modules/mod_manage_projects.php
@@ -50,8 +50,8 @@ $can_edit = $user->is_admin || ($organization_id == $user_organization_id);
// Only admins and mentors can access
$user->restrict($role == 'm', true);
-$organization_select = build_organization_select($program_id, $organization_id, false,
- null, "organizationSelect");
+$organization_select = build_organization_select($program_id, $organization_id, false, false,
+ false, null, "organizationSelect");
if ($organization_id > 0) {
$sql = "SELECT * FROM {$db->prefix}projects prj " .
diff --git a/modules/mod_program_home.php b/modules/mod_program_home.php
index 8f0d93d..dc82adf 100644
--- a/modules/mod_program_home.php
+++ b/modules/mod_program_home.php
@@ -18,13 +18,12 @@ if ($program_data != null)
$user->get_role($id, $role, $organization);
// Set object availability based on deadlines
- $show_student = true;
$show_mentor = true;
- if ($core->timestamp >= $program_data['dl_student'])
- {
- $show_student = false;
- }
+ $project_permissions = get_project_permissions($program_data, $role, null);
+
+ $show_student = $project_permissions->can_submit;
+ $late_submission = $project_permissions->late_submission;
if ($core->timestamp >= $program_data['dl_mentor'])
{
@@ -54,6 +53,7 @@ if ($program_data != null)
'prg_interm_visibility' => $skin->visibility($role == 'i'),
'prg_mentor_visibility' => $skin->visibility($role == 'm'),
'dl_student_visibility' => $skin->visibility($show_student),
+ 'late_submission_visibility' => $skin->visibility($late_submission),
'dl_mentor_visibility' => $skin->visibility($show_mentor),
'started_visibility' => $skin->visibility($role == 'g' && !($show_student || $show_mentor)),
'prog_adm_visibility' => $skin->visibility($user->is_admin),
diff --git a/modules/mod_view_projects.php b/modules/mod_view_projects.php
index 1a43c17..56d7a1e 100644
--- a/modules/mod_view_projects.php
+++ b/modules/mod_view_projects.php
@@ -28,32 +28,23 @@ $mentor_remove = isset($_POST['mentor_remove']);
$project_save = isset($_POST['project_save']);
$confirm = isset($_POST['yes']);
-// Validate project and program ID
+// Get information about the user and program, and project
+$user->get_role($program_id, $role, $mentor_organization_id);
+$program_data = $cache->get_program_data($program_id);
+$user->restrict($program_data !== null);
+
if ($project_id > 0)
{
- $sql = "SELECT COUNT(*) AS count " .
- "FROM {$db->prefix}projects prj " .
- "LEFT JOIN {$db->prefix}programs prg " .
- "ON prg.id = prj.program_id " .
- "WHERE prj.id = :project_id " .
- "AND prg.id = :program_id " .
- (!$user->is_admin ? "AND prg.is_active = 1" : "");
+ $project_data = $cache->get_project_data($project_id);
+
+ $user->restrict($project_data !== null);
+ $user->restrict($project_data['program_id'] == $program_id);
}
else
{
- $sql = "SELECT COUNT(*) AS count " .
- "FROM {$db->prefix}programs " .
- "WHERE id = :program_id " .
- (!$user->is_admin ? "AND is_active = 1" : "");
+ $project_data = null;
}
-$row = $db->query($sql,
- array('program_id' => $program_id,
- 'project_id' => $project_id),
- true);
-
-$user->restrict($row['count'] > 0);
-
// Validate organization_id
if ($organization_id > 0) {
$sql = "SELECT COUNT(*) AS count " .
@@ -70,88 +61,66 @@ if ($organization_id > 0) {
$user->restrict($row['count'] > 0);
}
-// Get the role of the user
-$user->get_role($program_id, $role, $organization);
-
-// Check if the user is the owner of the project
-if ($project_id > 0)
-{
- $sql = "SELECT COUNT(*) AS count " .
- "FROM {$db->prefix}projects prj " .
- "LEFT JOIN {$db->prefix}participants prt " .
- "ON prj.id = prt.project_id " .
- "WHERE prj.id = :project_id " .
- "AND prt.username = :username " .
- "AND (prt.role = 's' " .
- "OR (prt.role = 'm' " .
- "AND prj.is_accepted = 1))";
- $owner_count = $db->query($sql,
- array('project_id' => $project_id,
- 'username' => $user->username),
- true);
-
- $is_owner = $owner_count['count'] > 0;
-}
-else
-{
- $is_owner = false;
-}
+$project_permissions = get_project_permissions($program_data, $role, $project_data);
+$is_owner = $project_permissions->is_owner;
// Serve the page based on the action
if ($action == 'editor')
{
$page_title = $project_id == 0 ? $lang->get('submit_proposal') : $lang->get('edit_project');
- // Program ID is mandatory for editor
- $user->restrict($program_id > 0);
-
// Validate pass status of student (should be 1, 0 or -1)
$user->restrict(in_array($is_passed, array(1, 0, -1)));
- // Only students can create new proposals
if ($project_id == 0)
- {
- $user->restrict($role == 's', true);
- }
-
- // Only owners can edit a project
+ $user->restrict($project_permissions->can_submit, true);
else
- {
- $user->restrict($is_owner, true);
- }
-
- // Past student deadline, don't let them submit or edit
- if ($role == 's')
- {
- $sql = "SELECT dl_student FROM {$db->prefix}programs " .
- "WHERE id = ?";
- $program_data = $db->query($sql, $program_id, true);
-
- $user->restrict($core->timestamp < $program_data['dl_student'], true);
- }
+ $user->restrict($project_permissions->can_edit, true);
- // Fetch project data
if ($project_id > 0)
{
- $sql = "SELECT * FROM {$db->prefix}projects prj " .
- "LEFT JOIN {$db->prefix}participants prt " .
- "ON prj.id = prt.project_id " .
- "WHERE prj.id = ? " .
- "AND prt.role = 's'";
- $project_data = $db->query($sql, $project_id, true);
-
- // Do not let anyone but admins edit rejected projects`
- $user->restrict($project_data['is_accepted'] != 0, true);
-
// Load data from DB only if new data wasn't POSTed
if (!$project_save)
{
+ // See if the student is passed
+ $sql = "SELECT prt.passed FROM {$db->prefix}projects prj " .
+ " LEFT JOIN {$db->prefix}participants prt " .
+ "ON prj.id = prt.project_id " .
+ "WHERE prj.id = ? " .
+ "AND prt.role = 's'";
+ $row = $db->query($sql, $project_id, true);
+
$title = $project_data['title'];
$description = $project_data['description'];
$organization_id = $project_data['organization_id'];
- $is_passed = $project_data['passed'];
+ $is_passed = $row['passed'];
$is_complete = $project_data['is_complete'];
}
+
+ if ($organization_id != $project_data['organization_id'])
+ {
+ if (!$project_permissions->can_change_organization)
+ {
+ $organization_change_valid = false;
+ }
+ else
+ {
+ // If the organization can be changed, make sure that the target organization
+ // is taking new proposals.
+ if (!$user->is_admin && $core->timestamp >= $program_data['dl_student'])
+ {
+ $organization_data = $cache->get_organization_data($project_data['organization_id']);
+ $organization_change_valid = $organization_data['late_submission'];
+ }
+ else
+ {
+ $organization_change_valid = true;
+ }
+ }
+
+ if (!$organization_change_valid)
+ $organization_id = $project_data['organization_id'];
+ }
}
// Only mentor/admins can mark project as complete and pass a student
@@ -358,12 +327,16 @@ if ($action == 'editor')
'project_title' => htmlspecialchars($title),
'project_description' => nl2br(htmlspecialchars($description)),
'new_mentor' => htmlspecialchars($new_mentor),
- 'organization_select' => build_organization_select($program_id, $organization_id, false),
+ 'organization_select' => build_organization_select($program_id, $organization_id,
+ false,
+ $project_permissions->late_submission,
+ $project_id != 0 &&
!$project_permissions->can_change_organization),
'success_message' => isset($success_message) ? $success_message : '',
'error_message' => isset($error_message) ? $error_message : '',
'success_visibility' => $skin->visibility(empty($success_message), true),
'error_visibility' => $skin->visibility(empty($error_message), true),
'new_visibility' => $skin->visibility($project_id == 0),
+ 'late_submission_visibility' => $skin->visibility($project_id == 0 &&
$project_permissions->late_submission),
'decision_visibility' => $skin->visibility($project_id > 0 && $can_decide),
'subscribe_visibility' => $skin->visibility(isset($show_subscribe)),
'newuser_visibility' => $skin->visibility($project_id > 0 && $user->is_admin),
@@ -419,10 +392,7 @@ else if ($action == 'view')
{
// Program and Project IDs are mandatory here
$user->restrict($program_id > 0 && $project_id > 0);
-
- // Get program, project and participant data
- $program_data = $cache->get_program_data($program_id);
- $project_data = $cache->get_project_data($project_id);
+ $user->restrict($project_permissions->can_view);
if ($project_data['organization_id'] != null)
$organization_data = $cache->get_organization_data($project_data['organization_id']);
@@ -440,10 +410,6 @@ else if ($action == 'view')
$cache->put("participant_{$project_id}", $participant_data, 'projects');
}
- // Now that we have project data, allow only owner, mentors, and admins
- // to view the project
- $user->restrict($role == 'm' || $is_owner, true);
-
// Only allow mentors and admins to view mentorship unless project is accepted
$can_view_mentor = $project_data['is_accepted'] == 1 || $user->is_admin || $role == 'm';
@@ -497,12 +463,6 @@ else if ($action == 'view')
$result = $lang->get('undecided');
}
- // Don't let students edit post student deadline or if project is rejected
- if ($role == 's' && $is_owner)
- {
- $is_owner = ($core->timestamp < $program_data['dl_student'] && $project_data['is_accepted'] != 0);
- }
-
// Only mentors and admins can view proposal status before mentor deadline
if ($role != 'm' && !$user->is_admin && $core->timestamp < $program_data['dl_mentor'])
{
@@ -622,13 +582,14 @@ else if ($action == 'view')
'success_message' => isset($success_message) ? $success_message : '',
'success_visibility' => $skin->visibility(empty($success_message), true),
'mentor_visibility' => $skin->visibility($can_view_mentor),
- 'edit_visibility' => $skin->visibility($is_owner || $user->is_admin),
- 'attach_visibility' => $skin->visibility($is_owner),
+ 'edit_visibility' => $skin->visibility($project_permissions->can_edit),
+ 'attach_visibility' => $skin->visibility($is_owner && $project_permissions->can_edit),
'attachments_visibility' => $skin->visibility(count($attachment_data) > 0),
'delete_visibility' => $skin->visibility($user->is_admin),
'mentor_project_visibility' => $skin->visibility($can_mentor),
'mentor_remove_visibility' => $skin->visibility($can_remove_mentor),
- 'actions_visibility' => $skin->visibility($is_owner || $can_mentor || $can_remove_mentor ||
$user->is_admin),
+ 'actions_visibility' => $skin->visibility(($is_owner && $project_permissions->can_edit) ||
+ $can_mentor || $can_remove_mentor ||
$user->is_admin),
'subscribe_visibility' => $skin->visibility(isset($show_subscribe)),
'approve_visibility' => $skin->visibility($can_approve),
'reject_visibility' => $skin->visibility($can_reject),
@@ -647,9 +608,6 @@ else if ($action == 'user' || $action == 'proposed' || $action == 'accepted' ||
// Program ID is mandatory here
$user->restrict($program_id > 0);
- // Get program data
- $program_data = $cache->get_program_data($program_id);
-
$params = array('program_id' => $program_id,
'username' => $user->username,
'i:start' => $limit_start,
@@ -856,9 +814,6 @@ else if ($action == 'apply')
'organization_id' => $organization_id > 0 ? $organization_id : null,
'username' => $user->username);
- // Get the program data
- $program_data = $cache->get_program_data($program_id);
-
// Set the new role based on action
$new_role = $category == 'student' ? 's' : 'i';
@@ -896,7 +851,7 @@ else if ($action == 'apply')
$core->redirect("?q=program_home&prg={$program_id}");
}
- $organization_select = build_organization_select($program_id, 0, true);
+ $organization_select = build_organization_select($program_id, 0, true, false);
// Assign final skin data
$skin->assign(array(
diff --git a/skins/easterngreen/html/tpl_program_home.html b/skins/easterngreen/html/tpl_program_home.html
index 3ab6545..d87f0da 100644
--- a/skins/easterngreen/html/tpl_program_home.html
+++ b/skins/easterngreen/html/tpl_program_home.html
@@ -96,6 +96,9 @@
{{view_submissions}}
</a>
+ <div class="alert alert-info [[late_submission_visibility]]">
+ {{late_submission_notice}}
+ </div>
<div class="resign-block">
<a href="?q=view_projects&prg=[[program_id]]&a=resign" class="btn btn-danger
btn-mini">
{{resign_program}}
diff --git a/skins/easterngreen/html/tpl_view_projects_editor.html
b/skins/easterngreen/html/tpl_view_projects_editor.html
index 5ca1420..8340cc5 100644
--- a/skins/easterngreen/html/tpl_view_projects_editor.html
+++ b/skins/easterngreen/html/tpl_view_projects_editor.html
@@ -30,6 +30,10 @@
</p>
</div>
+<div class="alert alert-info [[late_submission_visibility]]">
+ {{late_submission_notice}}
+</div>
+
<div class="control-group">
<label class="control-label">{{project_title}}</label>
<div class="controls">
diff --git a/utils.php b/utils.php
index c6f6b12..a777a76 100644
--- a/utils.php
+++ b/utils.php
@@ -1,5 +1,6 @@
<?php
-function build_organization_select($program_id, $current, $include_other, $name="o", $id=null)
+function build_organization_select($program_id, $current, $include_other, $only_late,
+ $disabled=false, $name="o", $id=null)
{
global $db, $lang;
@@ -11,8 +12,10 @@ function build_organization_select($program_id, $current, $include_other, $name=
$option_name = $lang->get('select_organization');
$n = ($name !== null) ? " name='{$name}'" : '';
$i = ($id !== null) ? " id='{$id}'" : '';
+ $d = $disabled ? " disabled" : '';
- $organization_select = "<select$n$i>";
+ echo $disabled;
+ $organization_select = "<select$n$i$d>";
$selected = $current == 0 ? " selected" : "";
$organization_select .= "<option value='0'$selected>{$option_name}</option>";
@@ -22,7 +25,8 @@ function build_organization_select($program_id, $current, $include_other, $name=
$organization_title = htmlspecialchars($row['title']);
$id = $row['id'];
$selected = $current == $id ? " selected" : "";
- $organization_select .= "<option value='$id'$selected>{$organization_title}</option>";
+ $d = ($only_late && $row['late_submission'] == 0) ? " disabled" : "";
+ $organization_select .= "<option value='$id'$selected$d>{$organization_title}</option>";
}
$option_name = $lang->get('other');
@@ -61,4 +65,103 @@ function opinion_is_valid($value) {
return in_array($value, $VALID_OPINIONS);
}
+class ProjectPermissions {
+
+ public $can_submit;
+ public $late_submission;
+ public $is_owner;
+ public $can_view;
+ public $can_edit;
+ public $can_change_organization;
+
+ function __construct($program_data, $role, $project_data) {
+ global $cache, $core, $db, $user;
+
+ $can_submit = false;
+ $late_submission = false;
+ $is_owner = false;
+ $can_view = false;
+ $can_edit = false;
+ $can_change_organization = false;
+
+ if ($role == 's') {
+ $can_submit = true;
+
+ if ($core->timestamp >= $program_data['dl_student'])
+ {
+ $can_submit = false;
+
+ if ($core->timestamp < $program_data['dl_mentor']) {
+ $sql = "SELECT COUNT(*) AS count from {$db->prefix}organizations " .
+ "WHERE program_id = ? AND late_submission = 1";
+ $row = $db->query($sql, $program_data['id'], true);
+ $late_submission = $row['count'] > 0;
+ if ($late_submission)
+ $can_submit = true;
+ }
+ }
+ }
+
+ if ($project_data !== null) {
+ $sql = "SELECT COUNT(*) AS count " .
+ "FROM {$db->prefix}projects prj " .
+ "LEFT JOIN {$db->prefix}participants prt " .
+ "ON prj.id = prt.project_id " .
+ "WHERE prj.id = :project_id " .
+ "AND prt.username = :username " .
+ "AND (prt.role = 's' " .
+ "OR (prt.role = 'm' " .
+ "AND prj.is_accepted = 1))";
+ $row = $db->query($sql,
+ array('project_id' => $project_data['id'],
+ 'username' => $user->username),
+ true);
+
+ $is_owner = $row['count'] > 0;
+
+ $can_view = $user->is_admin || $role =='m' || $is_owner;
+
+ if ($user->is_admin) {
+ $can_edit = true;
+ $can_change_organization = true;
+ } else if ($is_owner && $role == 's') {
+ $can_edit = true;
+ $can_change_organization = true;
+
+ // Do not let anyone but admins edit rejected projects`
+ if ($project_data['is_accepted'] == 0) {
+ $can_edit = false;
+ $can_change_organization = false;
+ } else if ($core->timestamp >= $program_data['dl_mentor']) {
+ // Past the selection deadline, students cannot edit anything
+ $can_edit = false;
+ $can_change_organization = false;
+ } else if ($core->timestamp > $program_data['dl_student']) {
+ // Projects submitted to organizations that are no longer taking
+ // new submissions can't be moved by the student to a different
+ // organization, because they can't be moved back.
+
+ if (!$can_submit) {
+ $can_change_organization = false;
+ } else if ($late_submission) {
+ $organization_data = $cache->get_organization_data($project_data['organization_id']);
+ $can_change_organization = $organization_data['late_submission'] != 0;
+ }
+ }
+ }
+ }
+
+ $this->can_submit = $can_submit;
+ $this->late_submission = $late_submission;
+ $this->is_owner = $is_owner;
+ $this->can_view = $can_view;
+ $this->can_edit = $can_edit;
+ $this->can_change_organization = $can_change_organization;
+ }
+}
+
+function get_project_permissions($program_data, $role, $project_data) {
+ return new ProjectPermissions($program_data, $role, $project_data);
+}
+
?>
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]