diff --git a/inc/ui/principal-edit.php b/inc/ui/principal-edit.php index 9363e3f2..2eef91ec 100644 --- a/inc/ui/principal-edit.php +++ b/inc/ui/principal-edit.php @@ -1,25 +1,39 @@ SetLookup( 'date_format_type', "SELECT 'E', 'European' UNION SELECT 'U', 'US Format' UNION SELECT 'I', 'ISO Format'" ); -$editor->SetLookup( 'type_id', 'SELECT principal_type_id, principal_type_desc FROM principal_type ORDER BY principal_type_id' ); -$editor->SetLookup( 'locale', 'SELECT \'\', \''.translate("*** Default Locale ***").'\' UNION SELECT locale, locale_name_locale FROM supported_locales ORDER BY 1 ASC' ); -$editor->AddAttribute( 'locale', 'title', translate("The preferred language for this person.") ); -$editor->AddAttribute( 'fullname', 'title', translate("The full name for this person, group or other type of principal.") ); param_to_global('id', 'int', 'old_id', 'principal_id' ); -$editor->SetWhere( 'principal_id='.$id ); - -$editor->AddField('is_admin', 'EXISTS( SELECT 1 FROM role_member WHERE role_no = 1 AND role_member.user_no = dav_principal.user_no )' ); -$editor->AddAttribute('is_admin', 'title', translate('An "Administrator" user has full rights to the whole DAViCal System')); $privilege_names = array( 'read', 'write-properties', 'write-content', 'unlock', 'read-acl', 'read-current-user-privilege-set', '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' ); +$privilege_xlate = array( + 'all' => translate('All privileges'), + 'read' => translate('Read'), + 'write-properties' => translate('Write Metadata'), + 'write-content' => translate('Write Data'), + 'unlock' => translate('Override a Lock'), + 'read-acl' => translate('Read Access Controls'), + 'read-current-user-privilege-set' => translate('Read Current User\'s Access'), + 'bind' => translate('Create Events/Collections'), + 'unbind' => translate('Delete Events/Collections'), + 'write-acl' => translate('Write Access Controls'), + 'read-free-busy' => translate('Read Free/Busy Information'), + 'schedule-deliver-invite' => translate('Scheduling: Deliver an Invitation'), + 'schedule-deliver-reply' => translate('Scheduling: Deliver a Reply'), + 'schedule-query-freebusy' => translate('Scheduling: Query free/busy'), + 'schedule-send-invite' => translate('Scheduling: Send an Invitation'), + 'schedule-send-reply' => translate('Scheduling: Send a Reply'), + 'schedule-send-freebusy' => translate('Scheduling: Send free/busy'), + 'write' => translate('Write'), + 'schedule-deliver' => translate('Scheduling: Delivery'), + 'schedule-send' => translate('Scheduling: Sending') +); + $delete_collection_confirmation_required = null; $delete_principal_confirmation_required = null; +$delete_ticket_confirmation_required = null; +$delete_bind_in_confirmation_required = null; +$delete_binding_confirmation_required = null; function handle_subaction( $subaction ) { global $session, $c, $id, $editor; @@ -139,198 +153,147 @@ function handle_subaction( $subaction ) { return false; } -if ( isset($_GET['subaction']) ) { - handle_subaction($_GET['subaction']); -} - - -$can_write_principal = ($session->AllowedTo('Admin') || $session->principal_id == $id ); -$post_values = false; - -if ( isset($_POST['xxxxusername']) ) { - $_POST['xxxxusername'] = trim(str_replace('/', '', $_POST['xxxxusername'])); - if ( $_POST['xxxxusername'] == '' ) { - $c->messages[] = i18n("The username must not be blank, and may not contain a slash"); +function principal_editor() { + global $id, $can_write_principal, $session; + $editor = new Editor(translate('Principal'), 'dav_principal'); + + $editor->SetLookup( 'date_format_type', "SELECT 'E', 'European' UNION SELECT 'U', 'US Format' UNION SELECT 'I', 'ISO Format'" ); + $editor->SetLookup( 'type_id', 'SELECT principal_type_id, principal_type_desc FROM principal_type ORDER BY principal_type_id' ); + $editor->SetLookup( 'locale', 'SELECT \'\', \''.translate("*** Default Locale ***").'\' UNION SELECT locale, locale_name_locale FROM supported_locales ORDER BY 1 ASC' ); + $editor->AddAttribute( 'locale', 'title', translate("The preferred language for this person.") ); + $editor->AddAttribute( 'fullname', 'title', translate("The full name for this person, group or other type of principal.") ); + $editor->SetWhere( 'principal_id='.$id ); + + $editor->AddField('is_admin', 'EXISTS( SELECT 1 FROM role_member WHERE role_no = 1 AND role_member.user_no = dav_principal.user_no )' ); + $editor->AddAttribute('is_admin', 'title', translate('An "Administrator" user has full rights to the whole DAViCal System')); + + $post_values = false; + + if ( isset($_POST['xxxxusername']) ) { + $_POST['xxxxusername'] = trim(str_replace('/', '', $_POST['xxxxusername'])); + if ( $_POST['xxxxusername'] == '' ) { + $c->messages[] = i18n("The username must not be blank, and may not contain a slash"); + $can_write_principal = false; + } + }; + if ( isset($_POST['fullname']) && trim($_POST['fullname']) == '' ) { + $c->messages[] = i18n("The full name must not be blank."); $can_write_principal = false; + }; + if ( isset($_POST['email']) && trim($_POST['email']) == '' ) { + $c->messages[] = i18n("The email address really should not be blank."); } -}; -if ( isset($_POST['fullname']) && trim($_POST['fullname']) == '' ) { - $c->messages[] = i18n("The full name must not be blank."); - $can_write_principal = false; -}; -if ( isset($_POST['email']) && trim($_POST['email']) == '' ) { - $c->messages[] = i18n("The email address really should not be blank."); -} - -$pwstars = '@@@@@@@@@@'; -if ( $can_write_principal && $editor->IsSubmit() ) { - $editor->WhereNewRecord( "principal_id=(SELECT CURRVAL('dav_id_seq'))" ); - if ( ! $session->AllowedTo('Admin') ) { - unset($_POST['admin_role']); - unset($_POST['user_active']); - } - unset($_POST['password']); - if ( $_POST['newpass1'] != '' && $_POST['newpass1'] != $pwstars ) { - if ( $_POST['newpass1'] == $_POST['newpass2'] ) { - $_POST['password'] = $_POST['newpass1']; + + $pwstars = '@@@@@@@@@@'; + if ( $can_write_principal && $editor->IsSubmit() ) { + $editor->WhereNewRecord( "principal_id=(SELECT CURRVAL('dav_id_seq'))" ); + if ( ! $session->AllowedTo('Admin') ) { + unset($_POST['admin_role']); + unset($_POST['user_active']); + } + unset($_POST['password']); + if ( $_POST['newpass1'] != '' && $_POST['newpass1'] != $pwstars ) { + if ( $_POST['newpass1'] == $_POST['newpass2'] ) { + $_POST['password'] = $_POST['newpass1']; + } + else { + $c->messages[] = "Password not updated. The supplied passwords do not match."; + } + } + if ( isset($_POST['fullname']) && !isset($_POST['displayname']) ) { + $_POST['displayname'] = $_POST['fullname']; + } + if ( isset($_POST['default_privileges']) ) { + $privilege_bitpos = array_flip($privilege_names); + $priv_names = array_keys($_POST['default_privileges']); + $privs = privilege_to_bits($priv_names); + $_POST['default_privileges'] = sprintf('%024s',decbin($privs)); + $editor->Assign('default_privileges', $privs_dec); + } + if ( $editor->IsCreate() ) { + $c->messages[] = i18n("Creating new Principal record."); } else { - $c->messages[] = "Password not updated. The supplied passwords do not match."; + $c->messages[] = i18n("Updating Principal record."); + } + $editor->Write(); + if ( $_POST['type_id'] != 3 && $editor->IsCreate() ) { + /** We only add the default calendar if it isn't a group, and this is a create action */ + require_once('auth-functions.php'); + CreateHomeCalendar($editor->Value('username')); + } + if ( $session->AllowedTo('Admin') ) { + if ( $_POST['is_admin'] == 'on' ) { + $sql = 'INSERT INTO role_member (role_no, user_no) SELECT 1, dav_principal.user_no FROM dav_principal WHERE user_no = :user_no AND NOT EXISTS(SELECT 1 FROM role_member rm WHERE rm.role_no = 1 AND rm.user_no = dav_principal.user_no )'; + $editor->Assign('is_admin', 't'); + } + else { + $sql = 'DELETE FROM role_member WHERE role_no = 1 AND user_no = :user_no'; + $editor->Assign('is_admin', 'f'); + } + $params[':user_no'] = $editor->Value('user_no'); + $qry = new AwlQuery( $sql, $params ); + $qry->Exec('admin-principal-edit'); } } - if ( isset($_POST['fullname']) && !isset($_POST['displayname']) ) { - $_POST['displayname'] = $_POST['fullname']; + else if ( isset($id) && $id > 0 ) { + $editor->GetRecord(); + if ( $editor->IsSubmit() ) { + $c->messages[] = i18n('You do not have permission to modify this record.'); + } } - if ( isset($_POST['default_privileges']) ) { - $privilege_bitpos = array_flip($privilege_names); - $priv_names = array_keys($_POST['default_privileges']); - $privs = privilege_to_bits($priv_names); - $_POST['default_privileges'] = sprintf('%024s',decbin($privs)); - $editor->Assign('default_privileges', $privs_dec); - } - if ( $editor->IsCreate() ) { - $c->messages[] = i18n("Creating new Principal record."); + if ( $editor->Available() ) { + $c->page_title = $editor->Title(translate('Principal').': '.$editor->Value('fullname')); } else { - $c->messages[] = i18n("Updating Principal record."); + $c->page_title = $editor->Title(translate('Create New Principal')); + $privs = decbin(privilege_to_bits($c->default_privileges)); + $editor->Assign('default_privileges', $privs); + $editor->Assign('user_active', 't'); + foreach( $c->template_usr AS $k => $v ) { + $editor->Assign($k, $v); + } } - $editor->Write(); - if ( $_POST['type_id'] != 3 && $editor->IsCreate() ) { - /** We only add the default calendar if it isn't a group, and this is a create action */ - require_once('auth-functions.php'); - CreateHomeCalendar($editor->Value('username')); + if ( $post_values ) { + $editor->PostToValues(); + if ( isset($_POST['default_privileges']) ) { + $privilege_bitpos = array_flip($privilege_names); + $priv_names = array_keys($_POST['default_privileges']); + $privs = privilege_to_bits($priv_names); + $_POST['default_privileges'] = sprintf('%024s',decbin($privs)); + $editor->Assign('default_privileges', $_POST['default_privileges']); + } } + + + $prompt_principal_id = translate('Principal ID'); + $value_id = ( $editor->Available() ? '##principal_id.hidden####principal_id.value##' : translate('New Principal')); + $prompt_username = translate('Username'); + $prompt_password_1 = translate('Change Password'); + $prompt_password_2 = translate('Confirm Password'); + $prompt_fullname = translate('Fullname'); + $prompt_displayname = translate('Display Name'); + $prompt_email = translate('Email Address'); + $prompt_date_format = translate('Date Format Style'); + $prompt_admin = translate('Administrator'); + $prompt_active = translate('Active'); + $prompt_locale = translate('Locale'); + $prompt_type = translate('Principal Type'); + $prompt_privileges = translate('Privileges granted to All Users'); + + $privs_html = build_privileges_html( $editor, 'default_privileges'); + + $admin_row_entry = ''; + $delete_principal_button = ''; if ( $session->AllowedTo('Admin') ) { - if ( $_POST['is_admin'] == 'on' ) { - $sql = 'INSERT INTO role_member (role_no, user_no) SELECT 1, dav_principal.user_no FROM dav_principal WHERE user_no = :user_no AND NOT EXISTS(SELECT 1 FROM role_member rm WHERE rm.role_no = 1 AND rm.user_no = dav_principal.user_no )'; - $editor->Assign('is_admin', 't'); - } - else { - $sql = 'DELETE FROM role_member WHERE role_no = 1 AND user_no = :user_no'; - $editor->Assign('is_admin', 'f'); - } - $params[':user_no'] = $editor->Value('user_no'); - $qry = new AwlQuery( $sql, $params ); - $qry->Exec('admin-principal-edit'); + $admin_row_entry = ' '.$prompt_admin.':##is_admin.checkbox## '; + $admin_row_entry .= ' '.$prompt_active.':##user_active.checkbox## '; + if ( isset($id) ) + $delete_principal_button = '' . translate("Delete Principal") . ''; } -} -else if ( isset($id) && $id > 0 ) { - $editor->GetRecord(); - if ( $editor->IsSubmit() ) { - $c->messages[] = i18n('You do not have permission to modify this record.'); - } -} -if ( $editor->Available() ) { - $c->page_title = $editor->Title(translate('Principal').': '.$editor->Value('fullname')); -} -else { - $c->page_title = $editor->Title(translate('Create New Principal')); - $privs = decbin(privilege_to_bits($c->default_privileges)); - $editor->Assign('default_privileges', $privs); - $editor->Assign('user_active', 't'); - foreach( $c->template_usr AS $k => $v ) { - $editor->Assign($k, $v); - } -} -if ( $post_values ) { - $editor->PostToValues(); - if ( isset($_POST['default_privileges']) ) { - $privilege_bitpos = array_flip($privilege_names); - $priv_names = array_keys($_POST['default_privileges']); - $privs = privilege_to_bits($priv_names); - $_POST['default_privileges'] = sprintf('%024s',decbin($privs)); - $editor->Assign('default_privileges', $_POST['default_privileges']); - } -} - -$privilege_xlate = array( - 'all' => translate('All privileges'), - 'read' => translate('Read'), - 'write-properties' => translate('Write Metadata'), - 'write-content' => translate('Write Data'), - 'unlock' => translate('Override a Lock'), - 'read-acl' => translate('Read Access Controls'), - 'read-current-user-privilege-set' => translate('Read Current User\'s Access'), - 'bind' => translate('Create Events/Collections'), - 'unbind' => translate('Delete Events/Collections'), - 'write-acl' => translate('Write Access Controls'), - 'read-free-busy' => translate('Read Free/Busy Information'), - 'schedule-deliver-invite' => translate('Scheduling: Deliver an Invitation'), - 'schedule-deliver-reply' => translate('Scheduling: Deliver a Reply'), - 'schedule-query-freebusy' => translate('Scheduling: Query free/busy'), - 'schedule-send-invite' => translate('Scheduling: Send an Invitation'), - 'schedule-send-reply' => translate('Scheduling: Send a Reply'), - 'schedule-send-freebusy' => translate('Scheduling: Send free/busy'), - 'write' => translate('Write'), - 'schedule-deliver' => translate('Scheduling: Delivery'), - 'schedule-send' => translate('Scheduling: Sending') -); - -/** -* privilege_format_function is for formatting the binary privileges from the -* database, including localising them. This is a hook function for a browser -* column object, so it takes three parameters: -* @param mixed $value The value of the column. -* @param BrowserColumn $column The BrowserColumn object we are hooked into. -* @param dbrow $row The row object we read from the database. -* @return string The formatted privileges. -*/ -function privilege_format_function( $value, $column, $row ) { - global $privilege_xlate; - - $privs = bits_to_privilege($value); - $formatted = ''; - foreach( $privs AS $k => $v ) { - $formatted .= ($formatted == '' ? '' : ' , '); - $v = preg_replace( '{^.*:}', '', $v ); - $formatted .= (isset($privilege_xlate[$v]) ? $privilege_xlate[$v] : $v ); - } - return $formatted; -} - - - -$default_privileges = bindec($editor->Value('default_privileges')); -$privileges_set = '
'; -for( $i=0; $i'.$privilege_xlate[$privilege_names[$i]].''."\n"; -} -$privileges_set .= '
'; - -$prompt_principal_id = translate('Principal ID'); -$value_id = ( $editor->Available() ? '##principal_id.hidden####principal_id.value##' : translate('New Principal')); -$prompt_username = translate('Username'); -$prompt_password_1 = translate('Change Password'); -$prompt_password_2 = translate('Confirm Password'); -$prompt_fullname = translate('Fullname'); -$prompt_displayname = translate('Display Name'); -$prompt_email = translate('Email Address'); -$prompt_date_format = translate('Date Format Style'); -$prompt_admin = translate('Administrator'); -$prompt_active = translate('Active'); -$prompt_locale = translate('Locale'); -$prompt_type = translate('Principal Type'); -$prompt_privileges = translate('Privileges granted to All Users'); - -$btn_all = htmlspecialchars(translate('All')); $btn_all_title = htmlspecialchars(translate('Toggle all privileges')); -$btn_rw = htmlspecialchars(translate('Read/Write')); $btn_rw_title = htmlspecialchars(translate('Set read+write privileges')); -$btn_read = htmlspecialchars(translate('Read')); $btn_read_title = htmlspecialchars(translate('Set read privileges')); -$btn_fb = htmlspecialchars(translate('Free/Busy')); $btn_fb_title = htmlspecialchars(translate('Set free/busy privileges')); -$btn_sd = htmlspecialchars(translate('Schedule Deliver')); $btn_sd_title = htmlspecialchars(translate('Set schedule-deliver privileges')); -$btn_ss = htmlspecialchars(translate('Schedule Send')); $btn_ss_title = htmlspecialchars(translate('Set schedule-deliver privileges')); - -$admin_row_entry = ''; -$delete_principal_button = ''; -if ( $session->AllowedTo('Admin') ) { - $admin_row_entry = ' '.$prompt_admin.':##is_admin.checkbox## '; - $admin_row_entry .= ' '.$prompt_active.':##user_active.checkbox## '; - if ( isset($id) ) - $delete_principal_button = '' . translate("Delete Principal") . ''; -} - -$id = $editor->Value('principal_id'); -$template = <<Value('principal_id'); + $template = << function toggle_privileges() { @@ -395,44 +358,96 @@ label.privilege { $prompt_date_format: ##date_format_type.select## $prompt_type: ##type_id.select## $admin_row_entry - $prompt_privileges: - - - - - - -
$privileges_set + $prompt_privileges:$privs_html ##submit## EOTEMPLATE; -$editor->SetTemplate( $template ); -$page_elements[] = $editor; - -if ( isset($delete_principal_confirmation_required) ) { - $html = '

'; - $html .= sprintf('%s \'%s\' %s %s', - translate('Deleting Principal:'), $editor->Value('displayname'), $_SERVER['REQUEST_URI'], - $delete_principal_confirmation_required, translate('Confirm Deletion of the Principal'), - translate('All of the principal\'s calendars and events will be unrecoverably deleted.') ); - $html .= "

\n"; - $page_elements[] = $html; + $editor->SetTemplate( $template ); + return $editor; } -if ( isset($id) && $id > 0 ) { +function build_privileges_html( $ed, $fname ) { + global $privilege_xlate, $privilege_names; + + $btn_all = htmlspecialchars(translate('All')); $btn_all_title = htmlspecialchars(translate('Toggle all privileges')); + $btn_rw = htmlspecialchars(translate('Read/Write')); $btn_rw_title = htmlspecialchars(translate('Set read+write privileges')); + $btn_read = htmlspecialchars(translate('Read')); $btn_read_title = htmlspecialchars(translate('Set read privileges')); + $btn_fb = htmlspecialchars(translate('Free/Busy')); $btn_fb_title = htmlspecialchars(translate('Set free/busy privileges')); + $btn_sd = htmlspecialchars(translate('Schedule Deliver')); $btn_sd_title = htmlspecialchars(translate('Set schedule-deliver privileges')); + $btn_ss = htmlspecialchars(translate('Schedule Send')); $btn_ss_title = htmlspecialchars(translate('Set schedule-deliver privileges')); + + $privs_dec = bindec($ed->Value($fname)); + $privileges_set = '
'."\n"; + for( $i=0; $i < count($privilege_names); $i++ ) { + $privilege_set = ( (1 << $i) & $privs_dec ? ' CHECKED' : ''); + $privileges_set .= sprintf( ' '."\n", + $fname, $privilege_names[$i], $fname, $privilege_names[$i], $privilege_set, + $privilege_xlate[$privilege_names[$i]]); + } + $privileges_set .= '
'."\n"; + + $form_id = $ed->Id(); + $html = << + + + + + +
$privileges_set +EOTEMPLATE; + + return $html; +} + + +/** +* privilege_format_function is for formatting the binary privileges from the +* database, including localising them. This is a hook function for a browser +* column object, so it takes three parameters: +* @param mixed $value The value of the column. +* @param BrowserColumn $column The BrowserColumn object we are hooked into. +* @param dbrow $row The row object we read from the database. +* @return string The formatted privileges. +*/ +function privilege_format_function( $value, $column, $row ) { + global $privilege_xlate; + + $privs = bits_to_privilege($value,'*'); + $formatted = ''; + foreach( $privs AS $k => $v ) { + $formatted .= ($formatted == '' ? '' : ', '); + $v = preg_replace( '{^.*:}', '', $v ); + $formatted .= (isset($privilege_xlate[$v]) ? $privilege_xlate[$v] : $v ); + } + return $formatted; +} + + +function confirm_delete_principal($confirmation_hash, $displayname ) { + $html = '

'; + $html .= sprintf('%s \'%s\' %s %s', + translate('Deleting Principal:'), $displayname, $_SERVER['REQUEST_URI'], + $confirmation_hash, translate('Confirm Deletion of the Principal'), + translate('All of the principal\'s calendars and events will be unrecoverably deleted.') ); + $html .= "

\n"; + return $html; +} + + + +function group_memberships_browser() { + global $c, $id, $editor; $browser = new Browser(translate('Group Memberships')); - $c->stylesheets[] = 'css/browse.css'; - $c->scripts[] = 'js/browse.js'; $browser->AddColumn( 'group_id', translate('ID'), 'right', '##principal_link##' ); $rowurl = $c->base_url . '/admin.php?action=edit&t=principal&id='; @@ -453,42 +468,46 @@ if ( isset($id) && $id > 0 ) { $browser->RowFormat( '', '', '#even' ); } $browser->DoQuery(); - $page_elements[] = $browser; + return $browser; +} - if ( $editor->Value('type_id') == 3 ) { +function group_row_editor() { + global $c, $id, $editor, $can_write_principal; + $grouprow = new Editor("Group Members", "group_member"); + $grouprow->SetLookup( 'member_id', 'SELECT principal_id, coalesce(displayname,fullname,username) FROM dav_principal WHERE principal_id NOT IN (SELECT member_id FROM group_member WHERE group_id = '.$id.') AND principal_id != '.$id); + $grouprow->SetSubmitName( 'savegrouprow' ); - $grouprow = new Editor("Group Members", "group_member"); - $grouprow->SetLookup( 'member_id', 'SELECT principal_id, coalesce(displayname,fullname,username) FROM dav_principal WHERE principal_id NOT IN (SELECT member_id FROM group_member WHERE group_id = '.$id.') AND principal_id != '.$id); - $grouprow->SetSubmitName( 'savegrouprow' ); + if ( $can_write_principal ) { + if ( $grouprow->IsSubmit() ) { + if ( $grouprow->IsUpdate() ) + $c->messages[] = translate('Updating Member of this Group Principal'); + else + $c->messages[] = translate('Adding new member to this Group Principal'); - if ( $can_write_principal ) { - if ( $grouprow->IsSubmit() ) { - if ( $grouprow->IsUpdate() ) - $c->messages[] = translate('Updating Member of this Group Principal'); - else - $c->messages[] = translate('Adding new member to this Group Principal'); - - $_POST['group_id'] = $id; - $member_id = intval($_POST['member_id']); - $grouprow->SetWhere( "group_id=".qpg($id)." AND member_id=$member_id"); - $grouprow->Write( ); - unset($_GET['member_id']); - } - elseif ( isset($_GET['delete_member']) ) { - $qry = new AwlQuery("DELETE FROM group_member WHERE group_id=:group_id AND member_id = :member_id", - array( ':group_id' => $id, ':member_id' => intval($_GET['delete_member']) )); - $qry->Exec('principal-edit'); - $c->messages[] = translate('Member deleted from this Group Principal'); - } + $_POST['group_id'] = $id; + $member_id = intval($_POST['member_id']); + $grouprow->SetWhere( 'group_id='.$id.' AND member_id='.$member_id); + $grouprow->Write( ); + unset($_GET['member_id']); } + elseif ( isset($_GET['delete_member']) ) { + $qry = new AwlQuery('DELETE FROM group_member WHERE group_id=:group_id AND member_id = :member_id', + array( ':group_id' => $id, ':member_id' => intval($_GET['delete_member']) )); + $qry->Exec('principal-edit'); + $c->messages[] = translate('Member deleted from this Group Principal'); + } + } + return $grouprow; +} - function edit_group_row( $row_data ) { - global $grouprow, $id, $c; - $form_url = preg_replace( '#&(edit|delete)_group=\d+#', '', $_SERVER['REQUEST_URI'] ); +function edit_group_row( $row_data ) { + global $id, $c, $grouprow; - $template = << ##member_id.select##   ##Add.submit## @@ -497,138 +516,127 @@ if ( isset($id) && $id > 0 ) { EOTEMPLATE; - $grouprow->SetTemplate( $template ); - $grouprow->Title(""); - if ( $row_data->group_id > -1 ) $grouprow->SetRecord( $row_data ); + $grouprow->SetTemplate( $template ); + $grouprow->Title(""); + if ( $row_data->group_id > -1 ) $grouprow->SetRecord( $row_data ); - return $grouprow->Render(); - } + return $grouprow->Render(); +} - $browser = new Browser(translate('Group Members')); +function group_members_browser() { + global $c, $id, $editor, $can_write_principal; + $browser = new Browser(translate('Group Members')); - $browser->AddColumn( 'group_id', translate('ID'), 'right', '##principal_link##' ); - $rowurl = $c->base_url . '/admin.php?action=edit&t=principal&id='; - $browser->AddHidden( 'principal_id' ); - $browser->AddHidden( 'principal_link', "'' || principal_id || ''" ); - $browser->AddColumn( 'displayname', translate('Display Name') ); - $browser->AddColumn( 'member_of', translate('Is Member of'), '', '', 'is_member_of_list(principal_id)' ); - $browser->AddColumn( 'members', translate('Has Members'), '', '', 'has_members_list(principal_id)' ); + $browser->AddColumn( 'group_id', translate('ID'), 'right', '##principal_link##' ); + $rowurl = $c->base_url . '/admin.php?action=edit&t=principal&id='; + $browser->AddHidden( 'principal_id' ); + $browser->AddHidden( 'principal_link', "'' || principal_id || ''" ); + $browser->AddColumn( 'displayname', translate('Display Name') ); + $browser->AddColumn( 'member_of', translate('Is Member of'), '', '', 'is_member_of_list(principal_id)' ); + $browser->AddColumn( 'members', translate('Has Members'), '', '', 'has_members_list(principal_id)' ); - if ( $can_write_principal ) { - $del_link = ''.translate('Remove').''; - $browser->AddColumn( 'action', translate('Action'), 'center', '', "'$edit_link $del_link'" ); - } - - $browser->SetOrdering( 'displayname', 'A' ); - - $browser->SetJoins( "group_member LEFT JOIN dav_principal ON (member_id = principal_id) " ); - $browser->SetWhere( 'user_active AND group_id = '.$id ); - - if ( $c->enable_row_linking ) { - $browser->RowFormat( '', '', '#even' ); - } - else { - $browser->RowFormat( '', '', '#even' ); - } - $browser->DoQuery(); - $page_elements[] = $browser; - - if ( $can_write_principal ) { - $browser->RowFormat( '', '', '#even' ); - $extra_row = array( 'group_id' => -1 ); - $browser->MatchedRow('group_id', -1, 'edit_group_row'); - $extra_row = (object) $extra_row; - $browser->AddRow($extra_row); - } + if ( $can_write_principal ) { + $del_link = ''.translate('Remove').''; + $browser->AddColumn( 'action', translate('Action'), 'center', '', "'$edit_link $del_link'" ); } + $browser->SetOrdering( 'displayname', 'A' ); - $grantrow = new Editor("Grants", "grants"); - $grantrow->SetSubmitName( 'savegrantrow' ); - $edit_grant_clause = ''; - if ( isset($_GET['edit_grant']) ) { - $edit_grant_clause = ' AND to_principal != '.intval($_GET['edit_grant']); + $browser->SetJoins( "group_member LEFT JOIN dav_principal ON (member_id = principal_id) " ); + $browser->SetWhere( 'user_active AND group_id = '.$id ); + + if ( $c->enable_row_linking ) { + $browser->RowFormat( '', '', '#even' ); + } + else { + $browser->RowFormat( '', '', '#even' ); + } + $browser->DoQuery(); + + if ( $can_write_principal ) { + $browser->RowFormat( '', '', '#even' ); + $extra_row = array( 'group_id' => -1 ); + $browser->MatchedRow('group_id', -1, 'edit_group_row'); + $extra_row = (object) $extra_row; + $browser->AddRow($extra_row); + } + return $browser; +} + + +function grant_row_editor() { + global $c, $id, $editor, $can_write_principal, $privilege_names; + + $grantrow = new Editor("Grants", "grants"); + $grantrow->SetSubmitName( 'savegrantrow' ); + $edit_grant_clause = ''; + if ( isset($_GET['edit_grant']) ) { + $edit_grant_clause = ' AND to_principal != '.intval($_GET['edit_grant']); + } + $grantrow->SetLookup( 'to_principal', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_id NOT IN (SELECT to_principal FROM grants WHERE by_principal = '.$id.$edit_grant_clause.') ORDER BY fullname' ); + if ( $can_write_principal ) { + if ( $grantrow->IsSubmit() ) { + if ( $grantrow->IsUpdate() ) + $c->messages[] = translate('Updating grants by this Principal'); + else + $c->messages[] = translate('Granting new privileges from this Principal'); + $_POST['by_principal'] = $id; + $to_principal = intval($_POST['to_principal']); + $orig_to_id = intval($_POST['orig_to_id']); + $grantrow->SetWhere( 'by_principal='.$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_dec = privilege_to_bits($priv_names); + $_POST['privileges'] = sprintf('%024s',decbin($privs_dec)); + $grantrow->Assign('privileges', $privs_dec); + } + $grantrow->Write( ); + unset($_GET['to_principal']); } - $grantrow->SetLookup( 'to_principal', 'SELECT principal_id, displayname FROM dav_principal WHERE principal_id NOT IN (SELECT to_principal FROM grants WHERE by_principal = '.$id.$edit_grant_clause.') ORDER BY fullname' ); - if ( $can_write_principal ) { - if ( $grantrow->IsSubmit() ) { - if ( $grantrow->IsUpdate() ) - $c->messages[] = translate('Updating grants by this Principal'); - else - $c->messages[] = translate('Granting new privileges from this Principal'); - $_POST['by_principal'] = $id; - $to_principal = intval($_POST['to_principal']); - $orig_to_id = intval($_POST['orig_to_id']); - $grantrow->SetWhere( "by_principal=".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_principal=:grantor_id AND to_principal = :to_principal", - array( ':grantor_id' => $id, ':to_principal' => intval($_GET['delete_grant']) )); - $qry->Exec('principal-edit'); - $c->messages[] = translate('Deleted a grant from this Principal'); - } + elseif ( isset($_GET['delete_grant']) ) { + $qry = new AwlQuery("DELETE FROM grants WHERE by_principal=:grantor_id AND to_principal = :to_principal", + array( ':grantor_id' => $id, ':to_principal' => intval($_GET['delete_grant']) )); + $qry->Exec('principal-edit'); + $c->messages[] = translate('Deleted a grant from this Principal'); } + } + return $grantrow; +} - function edit_grant_row( $row_data ) { - global $grantrow, $id, $c, $privilege_xlate, $privilege_names; - global $btn_all, $btn_all_title, $btn_rw, $btn_rw_title, $btn_read, $btn_read_title; - global $btn_fb, $btn_fb_title, $btn_sd, $btn_sd_title, $btn_ss, $btn_ss_title; - if ( $row_data->to_principal > -1 ) { - $grantrow->SetRecord( $row_data ); - } +function edit_grant_row( $row_data ) { + global $id, $c, $grantrow; - $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 .= '
'; + if ( $row_data->to_principal > -1 ) { + $grantrow->Initialise( $row_data ); + } - $orig_to_id = $row_data->to_principal; - $form_id = $grantrow->Id(); - $form_url = preg_replace( '#&(edit|delete)_grant=\d+#', '', $_SERVER['REQUEST_URI'] ); + $privs_html = build_privileges_html( $grantrow, 'grant_privileges' ); - $template = <<to_principal; + $form_id = $grantrow->Id(); + $form_url = preg_replace( '#&(edit|delete)_grant=\d+#', '', $_SERVER['REQUEST_URI'] ); + + $template = << ##to_principal.select## - - - - - - - -
$privileges_set + $privs_html ##submit## EOTEMPLATE; - $grantrow->SetTemplate( $template ); - $grantrow->Title(""); + $grantrow->SetTemplate( $template ); + $grantrow->Title(""); - return $grantrow->Render(); - } + return $grantrow->Render(); +} - $browser = new Browser(translate('Principal Grants')); + +function principal_grants_browser() { + global $c, $id, $editor, $can_write_principal; + $browser = new Browser(translate('Principal Grants')); $browser->AddColumn( 'to_principal', translate('To ID'), 'right', '##principal_link##' ); $rowurl = $c->base_url . '/admin.php?action=edit&t=principal&id='; @@ -656,7 +664,6 @@ EOTEMPLATE; $browser->RowFormat( '', '', '#even' ); } $browser->DoQuery(); - $page_elements[] = $browser; if ( $can_write_principal ) { @@ -671,14 +678,103 @@ EOTEMPLATE; $browser->AddRow($extra_row); } } + return $browser; +} +function ticket_row_editor() { + global $c, $id, $editor, $can_write_principal, $privilege_names; + + $ticketrow = new Editor("Tickets", "access_ticket"); + $ticketrow->SetSubmitName( 'ticketrow' ); + dbg_error_log( "ERROR", "Creating ticketrow editor: %s - %s", $can_write_principal, $ticketrow->IsSubmit()); + if ( $can_write_principal && $ticketrow->IsSubmit() ) { + + $username = $editor->Value('username'); + $ugly_path = $_POST['target']; + if ( $ugly_path == '/'.$username || $ugly_path == '/'.$username.'/' ) { + $target_collection = $id; + } + else { + $username_len = strlen($username) + 2; + $sql = "SELECT collection_id FROM collection WHERE dav_name = :exact_name"; + $sql .= " AND substring(dav_name FROM 1 FOR $username_len) = '/$username/'"; + $params = array( ':exact_name' => $ugly_path ); + if ( !preg_match( '#/$#', $ugly_path ) ) { + $sql .= " OR dav_name = :truncated_name OR dav_name = :trailing_slash_name"; + $params[':truncated_name'] = preg_replace( '#[^/]*$#', '', $ugly_path); + $params[':trailing_slash_name'] = $ugly_path."/"; + } + $sql .= " ORDER BY LENGTH(dav_name) DESC LIMIT 1"; + $qry = new AwlQuery( $sql, $params ); + if ( $qry->Exec() && $qry->rows() > 0 ) { + $row = $qry->Fetch(); + $target_collection = $row->collection_id; + } + else { + $c->messages[] = translate('Can only add tickets for existing collection paths which you own'); + return $ticketrow; + } + } + + $_POST['dav_owner_id'] = $id; + $_POST['target_collection_id'] = $target_collection; + $ticket_id = clean_by_regex($_POST['ticket_id'], '/[A-Za-z0-9]+/'); + $ticketrow->SetWhere( 'dav_owner_id='.$id.' AND ticket_id='.AwlQuery::quote($ticket_id)); + if ( isset($_POST['ticket_privileges']) ) { + $privilege_bitpos = array_flip($privilege_names); + $priv_names = array_keys($_POST['ticket_privileges']); + $privs_dec = privilege_to_bits($priv_names); + $_POST['privileges'] = sprintf('%024s',decbin($privs_dec)); + $ticketrow->Assign('privileges', $privs_dec); + } + $c->messages[] = translate('Creating new ticket granting privileges to this Principal'); + $ticketrow->Write( ); + } + return $ticketrow; +} + + +function edit_ticket_row( $row_data ) { + global $id, $c, $ticketrow; + + if ( isset($row_data->ticket_id) ) { + $ticketrow->Initialise( $row_data ); + } + + $privs_html = build_privileges_html( $ticketrow, 'ticket_privileges' ); + + $form_id = $ticketrow->Id(); + $ticket_id = $row_data->ticket_id; + $form_url = preg_replace( '#&(edit|delete)_[a-z]+=\d+#', '', $_SERVER['REQUEST_URI'] ); + + $template = << + $ticket_id + + + $privs_html + ##submit## + + +EOTEMPLATE; + + $ticketrow->SetTemplate( $template ); + $ticketrow->Title(""); + + return $ticketrow->Render(); +} + + +function access_ticket_browser() { + global $c, $id, $editor, $can_write_principal; + $browser = new Browser(translate('Access Tickets')); $browser->AddColumn( 'ticket_id', translate('Ticket ID'), '', '' ); - $browser->AddColumn( 'target', translate('Target'), '', '%s', "'".$c->base_url.'/caldav.php'."' ||COALESCE(d.dav_name,c.dav_name)" ); - $browser->AddColumn( 'expiry', translate('Expires'), '', '', 'TO_CHAR(expires,\'YYYY-MM-DD HH:MI:SS\')'); - $browser->AddColumn( 'privs', translate('Privileges'), '', '', "privileges_list(privileges)" ); + $browser->AddColumn( 'target', translate('Target'), '', '%s', "COALESCE(d.dav_name,c.dav_name)" ); + $browser->AddColumn( 'expires', translate('Expires'), '', '', 'TO_CHAR(expires,\'YYYY-MM-DD HH:MI:SS\')'); + $browser->AddColumn( 'privs', translate('Privileges'), '', '', 'privileges', '', '', 'privilege_format_function' ); $delurl = $c->base_url . '/admin.php?action=edit&t=principal&id='.$id.'&ticket_id=##URL:ticket_id##&subaction=delete_ticket'; $browser->AddColumn( 'delete', translate('Action'), 'center', '', "'".translate('Delete')."'" ); @@ -687,24 +783,37 @@ EOTEMPLATE; $browser->SetJoins( 'access_ticket t LEFT JOIN collection c ON (target_collection_id=collection_id) LEFT JOIN caldav_data d ON (target_resource_id=dav_id)' ); $browser->SetWhere( 'dav_owner_id = '.intval($editor->Value('principal_id')) ); -// $browser->AddRow( array( 'target' => ''.translate('Create Ticket').'' )); - $browser->RowFormat( '', '', '#even' ); $browser->DoQuery(); - $page_elements[] = $browser; - if ( isset($delete_ticket_confirmation_required) ) { - $html = '
'; - $html .= sprintf('%s "%s" %s %s', - translate('Deleting Ticket:'), $_GET['ticket_id'], $_SERVER['REQUEST_URI'], - $delete_ticket_confirmation_required, - translate('Confirm Deletion of the Ticket'), - translate('The access ticket will be deleted.') ); - $html .= "
\n"; - $page_elements[] = $html; + if ( $can_write_principal ) { + $ticket_id = substr( str_replace('/', '', str_replace('+', '',base64_encode(sha1(date('r') .rand(0,2100000000) . microtime(true),true)))), 7, 8); + $extra_row = array( 'ticket_id' => $ticket_id, + 'expires' => date( 'Y-m-d', time() + (86400 * 31) ), + 'target' => '/'.$editor->Value('username').'/home/' + ); + $browser->MatchedRow('ticket_id', $ticket_id, 'edit_ticket_row'); + $browser->AddRow($extra_row); } + return $browser; +} + +function confirm_delete_ticket($confirmation_hash) { + $html = '
'; + $html .= sprintf('%s "%s" %s %s', + translate('Deleting Ticket:'), $_GET['ticket_id'], $_SERVER['REQUEST_URI'], + $confirmation_hash, + translate('Confirm Deletion of the Ticket'), + translate('The access ticket will be deleted.') ); + $html .= "
\n"; + return $html; +} + + +function principal_collection_browser() { + global $page_elements, $id, $editor; $browser = new Browser(translate('Principal Collections')); @@ -733,18 +842,22 @@ EOTEMPLATE; $browser->RowFormat( '', '', '#even' ); } $browser->DoQuery(); - $page_elements[] = $browser; - if ( isset($delete_collection_confirmation_required) ) { - $html = '
'; - $html .= sprintf('%s "%s" %s %s', - translate('Deleting Collection:'), $_GET['dav_name'], $_SERVER['REQUEST_URI'], - $delete_collection_confirmation_required, - translate('Confirm Deletion of the Collection'), - translate('All collection data will be unrecoverably deleted.') ); - $html .= "
\n"; - $page_elements[] = $html; - } + return $browser; +} + +function confirm_delete_collection($confirmation_hash) { + $html = '
'; + $html .= sprintf('%s "%s" %s %s', + translate('Deleting Collection:'), $_GET['dav_name'], $_SERVER['REQUEST_URI'], + $confirmation_hash, + translate('Confirm Deletion of the Collection'), + translate('All collection data will be unrecoverably deleted.') ); + $html .= "
\n"; + return $html; +} +function bindings_to_other_browser() { + global $page_elements, $id, $editor; $browser = new Browser(translate('Bindings to other collections')); $browser->AddColumn( 'bind_id', translate('ID'), '', '' ); $browser->AddHidden( 'b.dav_owner_id' ); @@ -764,20 +877,23 @@ EOTEMPLATE; $browser->RowFormat( '', '', '#even' ); $browser->DoQuery(); - $page_elements[] = $browser; - - if ( isset($delete_bind_in_confirmation_required) ) { - $html = '
'; - $html .= sprintf('%s "%s" %s %s', - translate('Deleting Binding:'), $_GET['bind_id'], $_SERVER['REQUEST_URI'], - $delete_bind_in_confirmation_required, - translate('Confirm Deletion of the Binding'), - translate('The binding will be deleted.') ); - $html .= "
\n"; - $page_elements[] = $html; - } + return $browser; +} + +function confirm_delete_bind_in($confirmation_hash) { + $html = '
'; + $html .= sprintf('%s "%s" %s %s', + translate('Deleting Binding:'), $_GET['bind_id'], $_SERVER['REQUEST_URI'], + $confirmation_hash, + translate('Confirm Deletion of the Binding'), + translate('The binding will be deleted.') ); + $html .= "
\n"; + return $html; +} +function bindings_to_us_browser() { + global $page_elements, $id, $editor; $browser = new Browser(translate('Bindings to this Principal\'s Collections')); $browser->AddColumn( 'bind_id', translate('ID'), '', '' ); $browser->AddHidden( 'b.dav_owner_id' ); @@ -797,17 +913,60 @@ EOTEMPLATE; $browser->RowFormat( '', '', '#even' ); $browser->DoQuery(); - $page_elements[] = $browser; - - if ( isset($delete_binding_confirmation_required) ) { - $html = '
'; - $html .= sprintf('%s "%s" %s %s', - translate('Deleting Binding:'), $_GET['bind_id'], $_SERVER['REQUEST_URI'], - $delete_binding_confirmation_required, - translate('Confirm Deletion of the Binding'), - translate('The binding will be deleted.') ); - $html .= "
\n"; - $page_elements[] = $html; - } - + return $browser; +} + +function confirm_delete_binding( $confirmation_hash ) { + $html = '
'; + $html .= sprintf('%s "%s" %s %s', + translate('Deleting Binding:'), $_GET['bind_id'], $_SERVER['REQUEST_URI'], + $confirmation_hash, + translate('Confirm Deletion of the Binding'), + translate('The binding will be deleted.') ); + $html .= "
\n"; + return $html; +} + + +if ( isset($_GET['subaction']) ) { + if ( handle_subaction($_GET['subaction']) && 'delete_principal' == $_GET['subaction'] ) { + return true; + } +} + + +$can_write_principal = ($session->AllowedTo('Admin') || $session->principal_id == $id ); + +$editor = principal_editor(); +$page_elements[] = $editor; + +if ( isset($id) && $id > 0 ) { + $c->stylesheets[] = 'css/browse.css'; + $c->scripts[] = 'js/browse.js'; + + if ( isset($delete_principal_confirmation_required) ) + $page_elements[] = confirm_delete_principal($delete_principal_confirmation_required, $editor->Value('displayname')); + + + $page_elements[] = group_memberships_browser(); + if ( $editor->Value('type_id') == 3 ) { + $grouprow = group_row_editor(); + $page_elements[] = group_members_browser(); + } + $grantrow = grant_row_editor(); + $page_elements[] = principal_grants_browser(); + if ( isset($delete_grant_confirmation_required) ) $page_elements[] = confirm_delete_grant($delete_grant_confirmation_required); + + $ticketrow = ticket_row_editor(); + $page_elements[] = access_ticket_browser(); + if ( isset($delete_ticket_confirmation_required) ) $page_elements[] = confirm_delete_ticket($delete_ticket_confirmation_required); + + $page_elements[] = principal_collection_browser(); + if ( isset($delete_collection_confirmation_required) ) $page_elements[] = confirm_delete_collection($delete_collection_confirmation_required); + + $page_elements[] = bindings_to_other_browser(); + if ( isset($delete_bind_in_confirmation_required) ) $page_elements[] = confirm_delete_bind_in($delete_bind_in_confirmation_required); + + $page_elements[] = bindings_to_us_browser(); + if ( isset($delete_binding_confirmation_required) ) $page_elements[] = confirm_delete_binding($delete_binding_confirmation_required); }