Index: trunk/core/kernel/application.php =================================================================== diff -u -N -r4626 -r4627 --- trunk/core/kernel/application.php (.../application.php) (revision 4626) +++ trunk/core/kernel/application.php (.../application.php) (revision 4627) @@ -1783,13 +1783,13 @@ * @param int $type permission type {1 - system, 0 - per category} * @return int */ - function CheckPermission($name, $type, $cat_id = null) + function CheckPermission($name, $type = 1, $cat_id = null) { - if ($this->GetVar('u_id') == -1 && ($name == 'ADMIN' || $name == 'LOGIN')) { - // "root" is permitted to login in any case - return 1; + if ($this->GetVar('u_id') == -1) { + // "root" is allowed anywhere + return $name == 'SYSTEM_ACCESS.READONLY' ? 0 : 1; } - + if ($type == 1) { // "system" permission are always checked per "Home" category (ID = 0) $cat_id = 0; Index: trunk/kernel/admin_templates/groups/permissions_selector.tpl =================================================================== diff -u -N -r4611 -r4627 --- trunk/kernel/admin_templates/groups/permissions_selector.tpl (.../permissions_selector.tpl) (revision 4611) +++ trunk/kernel/admin_templates/groups/permissions_selector.tpl (.../permissions_selector.tpl) (revision 4627) @@ -75,6 +75,7 @@ + Index: trunk/core/admin_templates/groups/permissions_selector.tpl =================================================================== diff -u -N -r4611 -r4627 --- trunk/core/admin_templates/groups/permissions_selector.tpl (.../permissions_selector.tpl) (revision 4611) +++ trunk/core/admin_templates/groups/permissions_selector.tpl (.../permissions_selector.tpl) (revision 4627) @@ -75,6 +75,7 @@ + Index: trunk/core/kernel/event_handler.php =================================================================== diff -u -N -r4625 -r4627 --- trunk/core/kernel/event_handler.php (.../event_handler.php) (revision 4625) +++ trunk/core/kernel/event_handler.php (.../event_handler.php) (revision 4627) @@ -61,21 +61,7 @@ */ function mapPermissions() { - $this->permMapping = Array( - 'OnCreate' => Array('self' => 'add', 'subitem' => 'add|edit'), - 'OnDelete' => Array('self' => 'delete', 'subitem' => 'edit|add'), - - 'OnEdit' => Array('self' => 'add|edit'), - 'OnPreCreate' => Array('self' => 'add'), - - 'OnPreSaveAndGoToTab' => Array('self' => 'add|edit'), - - // theese event do not harm, but just in case check them too :) - 'OnCancelEdit' => Array('self' => 'add|edit'), - 'OnCancel' => Array('self' => 'add|edit', 'subitem' => 'add|edit'), - - 'OnSetSorting' => Array('self' => 'view', 'subitem' => 'view'), - ); + } function getPrefixSpecial() @@ -322,23 +308,14 @@ */ function CheckPermission(&$event) { - if ($this->Application->GetVar('u_id') == -1) { - // "root" has all permissions - return true; - } - + $section = $event->getSection(); $main_prefix = $this->Application->GetTopmostPrefix($event->Prefix); - $section = $this->Application->getUnitOption($main_prefix, 'Section'); - - if (!$section) { - trigger_error('Permission section not specified for prefix '.$main_prefix.'', E_USER_ERROR); - } $pefix_type = ($main_prefix == $event->Prefix) ? 'self' : 'subitem'; $perm_mapping = getArrayValue($this->permMapping, $event->Name); if (!$perm_mapping[$pefix_type]) { - trigger_error('Permission mappings not defined for event '.$main_prefix.':'.$event->Name.'', E_USER_ERROR); + trigger_error('Permission mappings not defined for event '.$main_prefix.' <- '.$event->Prefix.':'.$event->Name.'', E_USER_ERROR); } $perm_status = false; @@ -370,6 +347,7 @@ $event->SetRedirectParam('section', $section); $event->SetRedirectParam('main_prefix', $main_prefix); $event->SetRedirectParam('event_name', $event->Name); + $event->status = erPERM_FAIL; } return $perm_status; } Index: trunk/core/kernel/db/db_event_handler.php =================================================================== diff -u -N -r4625 -r4627 --- trunk/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 4625) +++ trunk/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 4627) @@ -50,6 +50,63 @@ $this->Conn =& $this->Application->GetADODBConnection(); } + /** + * Checks permissions of user + * + * @param kEvent $event + */ + function CheckPermission(&$event) + { + if ($event->Name == 'OnSave') { + // check is made in OnPreSave subevent + return true; + } + + if (substr($event->Name, 0, 9) == 'OnPreSave') { + $section = $event->getSection(); + if ($this->isNewItemCreate($event)) { + return $this->Application->CheckPermission($section.'.add'); + } + else { + return $this->Application->CheckPermission($section.'.add', 1) || $this->Application->CheckPermission($section.'.edit', 1); + } + } + + return parent::CheckPermission($event); + } + + /** + * Allows to override standart permission mapping + * + */ + function mapPermissions() + { + parent::mapPermissions(); + $permissions = Array( + 'OnCreate' => Array('self' => 'add', 'subitem' => 'add|edit'), + 'OnDelete' => Array('self' => 'delete', 'subitem' => 'edit|add'), + 'OnMassDelete' => Array('self' => 'delete', 'subitem' => 'edit|add'), + 'OnSelectItems' => Array('self' => 'add|edit', 'subitem' => 'add|edit'), + + 'OnMassApprove' => Array('self' => 'advanced:approve|add|edit', 'subitem' => 'advanced:approve|add|edit'), + 'OnMassDecline' => Array('self' => 'advanced:decline|add|edit', 'subitem' => 'advanced:decline|add|edit'), + + + 'OnPreCreate' => Array('self' => 'add'), + 'OnEdit' => Array('self' => 'edit'), + + + + + // theese event do not harm, but just in case check them too :) + 'OnCancelEdit' => Array('self' => 'add|edit'), + 'OnCancel' => Array('self' => 'add|edit', 'subitem' => 'add|edit'), + + 'OnSetSorting' => Array('self' => 'view', 'subitem' => 'view'), + ); + $this->permMapping = array_merge($this->permMapping, $permissions); + } + function mapEvents() { $events_map = Array('OnRemoveFilters' => 'FilterAction', @@ -930,7 +987,20 @@ $this->Application->RemoveVar($event->getPrefixSpecial().'_modified'); } + /** + * Allows to determine if we are creating new item or editing already created item + * + * @param kEvent $event + * @return bool + */ + function isNewItemCreate(&$event) + { + $item_id = $this->getPassedID($event); + return ($item_id == '') ? true : false; + } + + /** * Saves edited item into temp table * If there is no id, new item is created in temp table * @@ -943,35 +1013,30 @@ if (is_object($event->MasterEvent)) { $event->MasterEvent->setEventParam('IsNew',false); } - $item_id = $this->getPassedID($event); - if($item_id == '') - { + + if ($this->isNewItemCreate($event)) { $event->CallSubEvent('OnPreSaveCreated'); if (is_object($event->MasterEvent)) { $event->MasterEvent->setEventParam('IsNew',true); } return; } - + $this->Application->setUnitOption($event->Prefix,'AutoLoad',false); $object =& $event->getObject(); $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); - if($items_info) - { - foreach($items_info as $id => $field_values) - { + if ($items_info) { + foreach ($items_info as $id => $field_values) { $object->SetDefaultValues(); $object->Load($id); $object->SetFieldsFromHash($field_values); - if( $object->Update($id) ) - { - $event->status=erSUCCESS; + if ($object->Update($id)) { + $event->status = erSUCCESS; } - else - { - $event->status=erFAIL; - $event->redirect=false; + else { + $event->status = erFAIL; + $event->redirect = false; break; } } Index: trunk/kernel/units/reviews/reviews_event_handler.php =================================================================== diff -u -N -r4303 -r4627 --- trunk/kernel/units/reviews/reviews_event_handler.php (.../reviews_event_handler.php) (revision 4303) +++ trunk/kernel/units/reviews/reviews_event_handler.php (.../reviews_event_handler.php) (revision 4627) @@ -93,11 +93,11 @@ $object->SetDBField('IPAddress', $_SERVER['REMOTE_ADDR']); $object->SetDBField('CreatedOn', adodb_mktime()); - if( $this->Application->CheckPermission('PRODUCT.REVIEW.PENDING') ) + if( $this->Application->CheckPermission('PRODUCT.REVIEW.PENDING', 0) ) { $object->SetDBField('Status', 2); } - elseif( $this->Application->CheckPermission('PRODUCT.REVIEW') ) + elseif( $this->Application->CheckPermission('PRODUCT.REVIEW', 0) ) { $object->SetDBField('Status', 1); } Index: trunk/core/kernel/utility/event.php =================================================================== diff -u -N -r4418 -r4627 --- trunk/core/kernel/utility/event.php (.../event.php) (revision 4418) +++ trunk/core/kernel/utility/event.php (.../event.php) (revision 4627) @@ -1,20 +1,4 @@ eventRunning($event_key); } + /** + * Returns section for current event + * + * @return string + */ + function getSection() + { + $main_prefix = $this->Application->GetTopmostPrefix($this->Prefix); + $section = $this->Application->getUnitOption($main_prefix, 'Section'); + + if (!$section) { + trigger_error('Permission section not specified for prefix '.$main_prefix.'', E_USER_ERROR); + } + return $section; + } + } ?> \ No newline at end of file Index: trunk/core/kernel/event_manager.php =================================================================== diff -u -N -r4626 -r4627 --- trunk/core/kernel/event_manager.php (.../event_manager.php) (revision 4626) +++ trunk/core/kernel/event_manager.php (.../event_manager.php) (revision 4627) @@ -267,18 +267,19 @@ $event->redirect = true; $event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler'); - if ($event_handler->CheckPermission($event)) { + if (($this->Application->GetVar('u_id') == -1) || $event_handler->CheckPermission($event)) { $this->HandleEvent($event); } - else { - $event->redirect = $event->getEventParam('no_permissions_template'); + + if ($event->status == erPERM_FAIL) { + $event->redirect = $event->getEventParam('no_permissions_template') ? $event->getEventParam('no_permissions_template') : 'no_permissions'; // restore stuff, that processOpener() changed $this->Application->RestoreVar('opener_stack'); $this->Application->SetVar('skip_last_template', $skip_last_template); - $this->Application->SetVar('m_opener', 's'); // stay, because "no_permission" template is not edit template } - if ($event->status == erSUCCESS && ($event->redirect === true || strlen($event->redirect) > 0)) { + // should do redirect but to no_permissions template + if ( ($event->status == erSUCCESS || $event->status == erPERM_FAIL) && ($event->redirect === true || strlen($event->redirect) > 0)) { $this->Application->Redirect($event->redirect, $event->redirect_params, null, $event->redirect_script); } } Index: trunk/kernel/admin_templates/no_permission.tpl =================================================================== diff -u -N -r4625 -r4627 --- trunk/kernel/admin_templates/no_permission.tpl (.../no_permission.tpl) (revision 4625) +++ trunk/kernel/admin_templates/no_permission.tpl (.../no_permission.tpl) (revision 4627) @@ -3,7 +3,9 @@ - + + + @@ -17,7 +19,11 @@ a_toolbar.AddButton( new ToolBarButton('prev', '', function() { - history.back(); + + window.close(); + + history.back(); + } ) ); a_toolbar.Render(); Index: trunk/kernel/constants.php =================================================================== diff -u -N -r4467 -r4627 --- trunk/kernel/constants.php (.../constants.php) (revision 4467) +++ trunk/kernel/constants.php (.../constants.php) (revision 4627) @@ -17,6 +17,12 @@ safeDefine('stTREE', 1); safeDefine('stTAB', 2); + // event statuses + define('erSUCCESS', 0); // event finished working succsessfully + define('erFAIL', -1); // event finished working, but result is unsuccsessfull + define('erFATAL', -2); // event experienced FATAL error - no hooks should continue! + define('erPERM_FAIL', -3); // event failed on internal permission checking (user has not permission) + $application =& kApplication::Instance(); $spacer_url = $application->BaseURL().'kernel/admin_templates/img/spacer.gif'; define('SPACER_URL', $spacer_url); Index: trunk/core/units/reviews/reviews_event_handler.php =================================================================== diff -u -N -r4303 -r4627 --- trunk/core/units/reviews/reviews_event_handler.php (.../reviews_event_handler.php) (revision 4303) +++ trunk/core/units/reviews/reviews_event_handler.php (.../reviews_event_handler.php) (revision 4627) @@ -93,11 +93,11 @@ $object->SetDBField('IPAddress', $_SERVER['REMOTE_ADDR']); $object->SetDBField('CreatedOn', adodb_mktime()); - if( $this->Application->CheckPermission('PRODUCT.REVIEW.PENDING') ) + if( $this->Application->CheckPermission('PRODUCT.REVIEW.PENDING', 0) ) { $object->SetDBField('Status', 2); } - elseif( $this->Application->CheckPermission('PRODUCT.REVIEW') ) + elseif( $this->Application->CheckPermission('PRODUCT.REVIEW', 0) ) { $object->SetDBField('Status', 1); }