r4103 getVLANSwitchTemplate(): asterisk SELECT is an evil, replace
authorDenis Ovsienko <infrastation@yandex.ru>
Wed, 12 Jan 2011 00:29:00 +0000 (00:29 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Wed, 12 Jan 2011 00:29:00 +0000 (00:29 +0000)
genericAssertion(): JSON gets spoiled in $_REQUEST, but not in $sic
commitUpdateVSTRules(): check mutex reliably, don't return anything, let exceptions roll transaction back
updVSTRule(): rewrite in a way with exceptions in mind

inc/database.php
inc/functions.php
inc/ophandlers.php

index 6af0571..d886b73 100644 (file)
@@ -4182,7 +4182,7 @@ function getVSTOptions()
 
 function getVLANSwitchTemplate ($vst_id)
 {
-       $result = usePreparedSelectBlade ('SELECT * FROM VLANSwitchTemplate WHERE id = ?', array ($vst_id));
+       $result = usePreparedSelectBlade ('SELECT id, description, mutex_rev, saved_by FROM VLANSwitchTemplate WHERE id = ?', array ($vst_id));
        if (!($ret = $result->fetch (PDO::FETCH_ASSOC)))
                throw new EntityNotFoundException ('vst', $vst_id);
        unset ($result);
@@ -4222,24 +4222,25 @@ function commitUpdateVSTRule ($vst_id, $rule_no, $new_rule_no, $port_pcre, $port
        );
 }
 
-function commitUpdateVSTRules ($vst_id, $rules)
+function commitUpdateVSTRules ($vst_id, $mutex_rev, $rules)
 {
        global $dbxlink, $remote_username;
        $dbxlink->beginTransaction();
-       try
-       {
-               usePreparedDeleteBlade ('VLANSTRule', array ('vst_id' => $vst_id));
-               foreach ($rules as $rule)
-                       usePreparedInsertBlade ('VLANSTRule', array_merge (array ('vst_id' => $vst_id), $rule));
-               usePreparedExecuteBlade ('UPDATE VLANSwitchTemplate SET mutex_rev=mutex_rev+1, saved_by=? WHERE id=?', array ($remote_username, $vst_id));
-       }
-       catch (Exception $e)
-       {
-               $dbxlink->rollBack();
-               return FALSE;
-       }
+       $result = usePreparedSelectBlade
+       (
+               'SELECT mutex_rev, saved_by FROM VLANSwitchTemplate ' .
+               'WHERE id = ? FOR UPDATE',
+               array ($vst_id)
+       );
+       $vst = $result->fetch (PDO::FETCH_ASSOC);
+       unset ($result);
+       if ($vst['mutex_rev'] != $mutex_rev)
+               throw new InvalidArgException ('mutex_rev', $mutex_rev, "already saved by ${vst['saved_by']}");
+       usePreparedDeleteBlade ('VLANSTRule', array ('vst_id' => $vst_id));
+       foreach ($rules as $rule)
+               usePreparedInsertBlade ('VLANSTRule', array_merge (array ('vst_id' => $vst_id), $rule));
+       usePreparedExecuteBlade ('UPDATE VLANSwitchTemplate SET mutex_rev=mutex_rev+1, saved_by=? WHERE id=?', array ($remote_username, $vst_id));
        $dbxlink->commit();
-       return TRUE;
 }
 
 function getIPv4Network8021QBindings ($ipv4net_id)
index 6c3774b..eb84ed6 100644 (file)
@@ -262,7 +262,7 @@ function genericAssertion ($argname, $argtype)
                break;
        case 'json':
                assertStringArg ($argname);
-               if (NULL === json_decode ($_REQUEST[$argname], TRUE))
+               if (NULL === json_decode ($sic[$argname], TRUE))
                        throw new InvalidRequestArgException ($argname, '(omitted)', 'Invalid JSON code received from client');
                break;
        case 'enum/attr_type':
index a1b050b..b4a8dfe 100644 (file)
@@ -2463,61 +2463,41 @@ function cloneVSTRule()
        return buildWideRedirectURL (array (array ('code' => $result ? 'success' : 'error', 'message' => $message)));
 }
 
+$msgcode['updVSTRule']['OK'] = 43;
 function updVSTRule()
 {
-       global $port_role_options;
+       global $port_role_options, $sic;
        assertUIntArg ('mutex_rev', TRUE);
-       assertStringArg ('template_json');
-       $message = '';
-       $data = json_decode ($_POST['template_json'], TRUE);
-       if (! isset ($data) or ! is_array ($data))
-               $message = 'Invalid JSON code received from client';
-       else
+       genericAssertion ('template_json', 'json');
+       $data = json_decode ($sic['template_json'], TRUE);
+       $rule_no = 0;
+       try
        {
-               $rule_no = 0;
                foreach ($data as $rule)
                {
                        $rule_no++;
-                       if (! isInteger ($rule['rule_no']))
-                               $message = 'Invalid rule number';
-                       elseif (! isPCRE ($rule['port_pcre']))
-                               $message = 'Invalid port regexp';
-                       elseif (! isset ($rule['port_role']) or ! array_key_exists ($rule['port_role'], $port_role_options))
-                               $message = 'Invalid port role';
-                       elseif (! isset ($rule['wrt_vlans']) or ! preg_match ('/^[ 0-9\-,]*$/', $rule['wrt_vlans']))
-                               $message = 'Invalid port vlan mask';
-                       elseif (! isset ($rule['description']))
-                               $message = 'Invalid description';
-
-                       if ($message)
-                       {
-                               $message .= " in rule $rule_no";
-                               break;
-                       }
-               }
-               if (! $message)
-               {
-                       $vst = getVLANSwitchTemplate ($_REQUEST['vst_id']);
-                       if ($vst['mutex_rev'] != $_REQUEST['mutex_rev'])
-                               $message = "User ${vst['saved_by']} saved this template after you started to edit it. Please concern differencies";
+                       if
+                       (
+                               ! isInteger ($rule['rule_no'])
+                               or ! isPCRE ($rule['port_pcre'])
+                               or ! isset ($rule['port_role'])
+                               or ! array_key_exists ($rule['port_role'], $port_role_options)
+                               or ! isset ($rule['wrt_vlans'])
+                               or ! preg_match ('/^[ 0-9\-,]*$/', $rule['wrt_vlans'])
+                               or ! isset ($rule['description'])
+                       )
+                               throw new InvalidRequestArgException ('form', '(JSON)', "invalid rule #$rule_no");
                }
-               if (! $message)
-                       if (! commitUpdateVSTRules ($_REQUEST['vst_id'], $data))
-                               $message = 'DB update error';
-               if ($message)
-                       $_SESSION['vst_edited'] = $data;
+               commitUpdateVSTRules ($_REQUEST['vst_id'], $_REQUEST['mutex_rev'], $data);
        }
-       if ($message)
-       {
-               $result = FALSE;
-               $message = "Template update failed: $message";
-       }
-       else
+       catch (Exception $e)
        {
-               $result = TRUE;
-               $message = "Update success";
+               // Every case, which is soft-processed in process.php, will have the working copy available for a retry.
+               if ($e instanceof InvalidRequestArgException or $e instanceof RTDatabaseError)
+                       $_SESSION['vst_edited'] = $data;
+               throw $e;
        }
-       return buildWideRedirectURL (array (array ('code' => $result ? 'success' : 'error', 'message' => $message)));
+       return buildRedirectURL (__FUNCTION__, 'OK');
 }
 
 $msgcode['importDPData']['OK'] = 44;