diff --git a/dba/create-database.sh b/dba/create-database.sh
index a1cbfc51..f632d351 100755
--- a/dba/create-database.sh
+++ b/dba/create-database.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
#
# Build the DAViCal database
#
diff --git a/dba/update-davical-database b/dba/update-davical-database
index 09810d4c..3d843500 100755
--- a/dba/update-davical-database
+++ b/dba/update-davical-database
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl -w
#
# Update the DAViCal database by repeatedly applying patches to it
# in the correct order.
diff --git a/htdocs/davical.css b/htdocs/davical.css
index 29724fea..7d54e5f9 100644
--- a/htdocs/davical.css
+++ b/htdocs/davical.css
@@ -4,6 +4,7 @@ body, p, li, td {
padding: 0;
margin: 0;
border: none;
+padding-bottom:2em;
}
.prompt {
diff --git a/inc/auth-functions.php b/inc/auth-functions.php
index 41996078..58ba29fc 100644
--- a/inc/auth-functions.php
+++ b/inc/auth-functions.php
@@ -128,7 +128,7 @@ function UpdateUserFromExternal( &$usr ) {
/**
* We disallow login by inactive users _after_ we have updated the local copy
*/
- if ( isset($usr->active) && $usr->active == 'f' ) return false;
+ if ( isset($usr->active) && ($usr->active === 'f' || $usr->active === false) ) return false;
if ( $type == 'INSERT' ) {
CreateHomeCalendar($usr->username);
diff --git a/inc/classEditor.php b/inc/classEditor.php
index 54bab1f6..e6effc05 100644
--- a/inc/classEditor.php
+++ b/inc/classEditor.php
@@ -25,7 +25,7 @@ class EditorField
var $LookupSql;
var $OptionList;
- function EditorField( $field, $sql="", $lookup_sql="" ) {
+ function __construct( $field, $sql="", $lookup_sql="" ) {
global $session;
$this->Field = $field;
$this->Sql = $sql;
@@ -116,7 +116,7 @@ class Editor
var $SubmitName;
var $Id;
- function Editor( $title = "", $fields = null ) {
+ function __construct( $title = "", $fields = null ) {
global $c, $session, $form_id_increment;
$this->Title = $title;
$this->Order = "";
@@ -156,7 +156,9 @@ class Editor
}
function SetLookup( $field, $lookup_sql ) {
- $this->Fields[$field]->SetLookup( $lookup_sql );
+ if (is_object($this->Fields[$field])) {
+ $this->Fields[$field]->SetLookup( $lookup_sql );
+ }
}
function Value( $value_field_name ) {
diff --git a/inc/ui/collection-edit.php b/inc/ui/collection-edit.php
index f04af8df..1348407c 100644
--- a/inc/ui/collection-edit.php
+++ b/inc/ui/collection-edit.php
@@ -17,8 +17,10 @@ $privilege_names = array( 'read', 'write-properties', 'write-content', 'unlock',
'bind', 'unbind', 'write-acl', 'read-free-busy', 'schedule-deliver-invite', 'schedule-deliver-reply',
'schedule-query-freebusy', 'schedule-send-invite', 'schedule-send-reply', 'schedule-send-freebusy' );
+$can_write_collection = ($session->AllowedTo('Admin') || $session->principal_id == $id );
+
$pwstars = '@@@@@@@@@@';
-if ( $editor->IsSubmit() ) {
+if ( $can_write_collection && $editor->IsSubmit() ) {
$editor->WhereNewRecord( "collection_id=(SELECT CURRVAL('dav_id_seq'))" );
if ( isset($_POST['default_privileges']) ) {
$privilege_bitpos = array_flip($privilege_names);
@@ -65,7 +67,7 @@ $default_privileges = bindec($editor->Value('default_privileges'));
$privileges_set = '
';
for( $i=0; $i'.$privilege_xlate[$privilege_names[$i]].''."\n";
+ $privileges_set .= ''."\n";
}
$privileges_set .= '
';
@@ -88,26 +90,29 @@ function toggle_privileges() {
var argv = toggle_privileges.arguments;
var argc = argv.length;
- if ( argc < 1 ) {
+ if ( argc < 2 ) {
return;
}
+ var match_me = argv[0];
var set_to = -1;
- if ( argv[0] == 'all' ) {
- var fieldcount = document.forms[0].elements.length;
+ if ( argv[1] == 'all' ) {
+ var form = document.getElementById(argv[2]);
+ var fieldcount = form.elements.length;
+ var matching = '/^' + match_me + '/';
for (var i = 0; i < fieldcount; i++) {
- var fieldname = document.forms[0].elements[i].name;
- if ( fieldname.match( /^default_privileges/ ) ) {
+ var fieldname = form.elements[i].name;
+ if ( fieldname.match( match_me ) ) {
if ( set_to == -1 ) {
- set_to = ( document.forms[0].elements[i].checked ? 0 : 1 );
+ set_to = ( form.elements[i].checked ? 0 : 1 );
}
- document.forms[0].elements[i].checked = set_to;
+ form.elements[i].checked = set_to;
}
}
}
else {
- for (var i = 0; i < argc; i++) {
- var f = document.getElementById( 'priv_checkbox_' + argv[i]);
+ for (var i = 1; i < argc; i++) {
+ var f = document.getElementById( match_me + '_' + argv[i]);
if ( set_to == -1 ) {
set_to = ( f.checked ? 0 : 1 );
}
@@ -148,19 +153,19 @@ label.privilege {
| $prompt_calendar: | ##is_calendar.checkbox## |
| $prompt_addressbook: | ##is_addressbook.checkbox## |
| $prompt_privileges: |
-
+
+ onclick="toggle_privileges('default_privileges', 'read', 'read-free-busy', 'schedule-query-freebusy', 'read-current-user-privilege-set' );">
+ onclick="toggle_privileges('default_privileges', 'read-free-busy', 'schedule-query-freebusy' );">
+ onclick="toggle_privileges('default_privileges', 'schedule-deliver-invite', 'schedule-deliver-reply', 'schedule-query-freebusy' );">
+ onclick="toggle_privileges('default_privileges', 'schedule-send-invite', 'schedule-send-reply', 'schedule-send-freebusy' );">
$privileges_set |
| $prompt_timezone: | ##timezone.select## |
| $prompt_schedule_transp: | ##schedule_transp.select## |
@@ -177,15 +182,97 @@ $page_elements[] = $editor;
$c->stylesheets[] = 'css/browse.css';
$c->scripts[] = 'js/browse.js';
+
+$grantrow = new Editor("Grants", "grants");
+$grantrow->SetSubmitName( 'savegrantrow' );
+$grantrow->SetLookup( 'to_principal', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_id NOT IN (SELECT member_id FROM group_member WHERE group_id = '.$id.')' );
+if ( $can_write_collection ) {
+ if ( $grantrow->IsSubmit() ) {
+ $_POST['by_collection'] = $id;
+ $to_principal = intval($_POST['to_principal']);
+ $orig_to_id = intval($_POST['orig_to_id']);
+ $grantrow->SetWhere( "by_collection=".qpg($id)." AND to_principal=$orig_to_id");
+ if ( isset($_POST['grant_privileges']) ) {
+ $privilege_bitpos = array_flip($privilege_names);
+ $priv_names = array_keys($_POST['grant_privileges']);
+ $privs = privilege_to_bits($priv_names);
+ $_POST['privileges'] = sprintf('%024s',decbin($privs));
+ $grantrow->Assign('privileges', $privs_dec);
+ }
+ $grantrow->Write( );
+ unset($_GET['to_principal']);
+ }
+ elseif ( isset($_GET['delete_grant']) ) {
+ $qry = new AwlQuery("DELETE FROM grants WHERE by_collection=:grantor_id AND to_principal = :to_principal",
+ array( ':grantor_id' => $id, ':to_principal' => intval($_GET['delete_grant']) ));
+ $qry->Exec('collection-edit');
+ }
+}
+
+function edit_grant_row( $row_data ) {
+ global $grantrow, $id, $privilege_xlate, $privilege_names;
+
+ if ( $row_data->to_principal > -1 ) {
+ $grantrow->SetRecord( $row_data );
+ }
+
+ $grant_privileges = bindec($grantrow->Value('grant_privileges'));
+ $privileges_set = '';
+ for( $i=0; $i < count($privilege_names); $i++ ) {
+ $privilege_set = ( (1 << $i) & $grant_privileges ? ' CHECKED' : '');
+ $privileges_set .= ''."\n";
+ }
+ $privileges_set .= '
';
+
+ $orig_to_id = $row_data->to_principal;
+ $form_id = $grantrow->Id();
+ $form_url = preg_replace( '#&(edit|delete)_grant=\d+#', '', $_SERVER['REQUEST_URI'] );
+
+ $template = <<
+ ##to_principal.select## |
+
+
+
+
+
+
+
+ $privileges_set
+ | ##submit## |
+
+
+EOTEMPLATE;
+
+ $grantrow->SetTemplate( $template );
+ $grantrow->Title("");
+
+ return $grantrow->Render();
+}
+
$browser = new Browser(translate('Collection Grants'));
$browser->AddColumn( 'to_principal', translate('To ID'), 'right', '##principal_link##' );
-$rowurl = $c->base_url . '/davical.php?action=edit&t=principal&id=';
+$rowurl = $c->base_url . '/davical.php?action=edit&t=collection&id=';
$browser->AddHidden( 'principal_link', "'' || to_principal || ''" );
+$browser->AddHidden( 'grant_privileges', 'privileges' );
$browser->AddColumn( 'displayname', translate('Display Name') );
$browser->AddColumn( 'privs', translate('Privileges'), '', '', 'privileges_list(privileges)' );
$browser->AddColumn( 'members', translate('Has Members'), '', '', 'has_members_list(principal_id)' );
+if ( $can_write_collection ) {
+ $del_link = "Delete";
+ $edit_link = "Edit";
+ $browser->AddColumn( 'action', 'Action', 'center', '', "'$edit_link $del_link'" );
+}
+
$browser->SetOrdering( 'displayname', 'A' );
$browser->SetJoins( "grants LEFT JOIN dav_principal ON (to_principal = principal_id) " );
@@ -200,5 +287,16 @@ else {
$browser->DoQuery();
$page_elements[] = $browser;
+if ( $can_write_collection ) {
+ if ( isset($_GET['edit_grant']) ) {
+ $browser->MatchedRow('to_principal', $_GET['edit_grant'], 'edit_grant_row');
+ }
+ else {
+ $extra_row = array( 'to_principal' => -1 );
+ $browser->MatchedRow('to_principal', -1, 'edit_grant_row');
+ $extra_row = (object) $extra_row;
+ $browser->AddRow($extra_row);
+ }
+}
diff --git a/inc/ui/principal-edit.php b/inc/ui/principal-edit.php
index 44ed0386..2637199a 100644
--- a/inc/ui/principal-edit.php
+++ b/inc/ui/principal-edit.php
@@ -72,7 +72,7 @@ $default_privileges = bindec($editor->Value('default_privileges'));
$privileges_set = '';
for( $i=0; $i'.$privilege_xlate[$privilege_names[$i]].''."\n";
+ $privileges_set .= ''."\n";
}
$privileges_set .= '
';
@@ -94,26 +94,29 @@ function toggle_privileges() {
var argv = toggle_privileges.arguments;
var argc = argv.length;
- if ( argc < 1 ) {
+ if ( argc < 2 ) {
return;
}
+ var match_me = argv[0];
var set_to = -1;
- if ( argv[0] == 'all' ) {
- var fieldcount = document.forms[0].elements.length;
+ if ( argv[1] == 'all' ) {
+ var form = document.getElementById(argv[2]);
+ var fieldcount = form.elements.length;
+ var matching = '/^' + match_me + '/';
for (var i = 0; i < fieldcount; i++) {
- var fieldname = document.forms[0].elements[i].name;
- if ( fieldname.match( /^default_privileges/ ) ) {
+ var fieldname = form.elements[i].name;
+ if ( fieldname.match( match_me ) ) {
if ( set_to == -1 ) {
- set_to = ( document.forms[0].elements[i].checked ? 0 : 1 );
+ set_to = ( form.elements[i].checked ? 0 : 1 );
}
- document.forms[0].elements[i].checked = set_to;
+ form.elements[i].checked = set_to;
}
}
}
else {
- for (var i = 0; i < argc; i++) {
- var f = document.getElementById( 'priv_checkbox_' + argv[i]);
+ for (var i = 1; i < argc; i++) {
+ var f = document.getElementById( match_me + '_' + argv[i]);
if ( set_to == -1 ) {
set_to = ( f.checked ? 0 : 1 );
}
@@ -142,19 +145,19 @@ label.privilege {
| $prompt_date_format: | ##date_format_type.select## |
| $prompt_type: | ##type_id.select## |
| $prompt_privileges: |
-
+
+ onclick="toggle_privileges('default_privileges', 'read', 'read-free-busy', 'schedule-query-freebusy', 'read-current-user-privilege-set' );">
+ onclick="toggle_privileges('default_privileges', 'read-free-busy', 'schedule-query-freebusy' );">
+ onclick="toggle_privileges('default_privileges', 'schedule-deliver-invite', 'schedule-deliver-reply', 'schedule-query-freebusy' );">
+ onclick="toggle_privileges('default_privileges', 'schedule-send-invite', 'schedule-send-reply', 'schedule-send-freebusy' );">
$privileges_set |
| ##submit## |
@@ -194,11 +197,6 @@ $page_elements[] = $browser;
if ( $editor->Value('type_id') == 3 ) {
$grouprow = new Editor("Group Members", "group_member");
- /**
- * @Todo: Need write-acl privs on the group user, too.
- */
- $priv_needed = privilege_to_bits('read-acl');
-// $grouprow->SetLookup( 'member_id', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_privileges('.$session->principal_id.',principal_id) & '.$priv_needed.'::BIT(24) != 0::BIT(24)');
$grouprow->SetLookup( 'member_id', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_id NOT IN (SELECT member_id FROM group_member WHERE group_id = '.$id.')');
$grouprow->SetSubmitName( 'savegrouprow' );
@@ -223,7 +221,7 @@ if ( $editor->Value('type_id') == 3 ) {
$form_url = preg_replace( '#&(edit|delete)_group=\d+#', '', $_SERVER['REQUEST_URI'] );
$template = <<
+
+
+EOTEMPLATE;
+
+ $grantrow->SetTemplate( $template );
+ $grantrow->Title("");
+
+ return $grantrow->Render();
+ }
+
$browser = new Browser(translate('Principal Grants'));
$browser->AddColumn( 'to_principal', translate('To ID'), 'right', '##principal_link##' );
$rowurl = $c->base_url . '/davical.php?action=edit&t=principal&id=';
$browser->AddHidden( 'principal_link', "'' || to_principal || ''" );
+$browser->AddHidden( 'grant_privileges', 'privileges' );
$browser->AddColumn( 'displayname', translate('Display Name') );
$browser->AddColumn( 'privs', translate('Privileges'), '', '', 'privileges_list(privileges)' );
$browser->AddColumn( 'members', translate('Has Members'), '', '', 'has_members_list(principal_id)' );
+if ( $can_write_principal ) {
+ $del_link = "Delete";
+ $edit_link = "Edit";
+ $browser->AddColumn( 'action', 'Action', 'center', '', "'$edit_link $del_link'" );
+}
+
$browser->SetOrdering( 'displayname', 'A' );
$browser->SetJoins( "grants LEFT JOIN dav_principal ON (to_principal = principal_id) " );
@@ -299,6 +378,18 @@ else {
$browser->DoQuery();
$page_elements[] = $browser;
+if ( $can_write_principal ) {
+ if ( isset($_GET['edit_grant']) ) {
+ $browser->MatchedRow('to_principal', $_GET['edit_grant'], 'edit_grant_row');
+ }
+ else {
+ $extra_row = array( 'to_principal' => -1 );
+ $browser->MatchedRow('to_principal', -1, 'edit_grant_row');
+ $extra_row = (object) $extra_row;
+ $browser->AddRow($extra_row);
+ }
+}
+
$browser = new Browser(translate('Principal Collections'));