public static function get_permission_sql($db_doc, $node_schema, $node_object, $node_permission, $action = 'grant')
 {
     if (strcasecmp($node_permission->getName(), 'grant') != 0 && strcasecmp($node_permission->getName(), 'revoke') != 0) {
         throw new exception("Cannot extract permission rights from node that is not grant or revoke");
     }
     if (!isset($node_permission['operation']) || strlen($node_permission['operation']) == 0) {
         throw new exception("node_permission operation definition is empty");
     }
     $object_name = '';
     $object_type = strtoupper($node_object->getName());
     $privileges = array_map(function ($p) use($object_type) {
         return mysql5_permission::get_real_privilege($p, $object_type);
     }, static::get_permission_privileges($node_permission));
     $roles = static::get_permission_roles($db_doc, $node_permission);
     $with = static::get_permission_options_sql($node_permission);
     switch ($object_type) {
         case 'SCHEMA':
             // all tables on current database, because no schemas
             $object_name = '*';
             break;
         case 'VIEW':
             return "-- Ignoring permissions on view '{$node_object['name']}' because MySQL uses SQL SECURITY DEFINER semantics\n";
         case 'TABLE':
             $object_name = mysql5::get_fully_qualified_table_name($node_schema['name'], $node_object['name']);
             break;
         case 'FUNCTION':
             $object_name = "FUNCTION " . mysql5::get_fully_qualified_object_name($node_schema['name'], $node_object['name'], 'function');
             break;
         case 'SEQUENCE':
             // sequences exist as rows in a table for mysql
             $object_name = mysql5::get_fully_qualified_table_name($node_schema['name'], mysql5_sequence::TABLE_NAME);
             break;
         default:
             throw new exception("unknown object type encountered: " . $object_type);
     }
     $sql = static::get_sql(strtoupper($action), $object_name, $privileges, array_map('mysql5::get_quoted_object_name', $roles), $with) . "\n";
     return $sql;
 }
Example #2
0
 public static function update_permissions($ofs1, $ofs3)
 {
     foreach (dbx::get_schemas(dbsteward::$new_database) as $new_schema) {
         $permissions = $new_schema->xpath('.//grant');
         foreach ($permissions as $node_permission) {
             $node_object = $node_permission->xpath('parent::*');
             $node_object = $node_object[0];
             if ($node_object === null) {
                 // I have a hard time imagining this could actually happen this far along, but better safe than sorry...
                 throw new Exception("Could not find parent node of permission GRANT {$node_permission['operation']} TO {$node_permission['role']}");
             }
             $ofs1->write(mysql5_permission::get_permission_sql(dbsteward::$new_database, $new_schema, $node_object, $node_permission, 'grant') . "\n");
         }
     }
 }
Example #3
0
 public static function build_schema($db_doc, $ofs, $table_depends)
 {
     // schema creation
     if (static::$use_schema_name_prefix) {
         dbsteward::info("MySQL schema name prefixing mode turned on");
     } else {
         if (count($db_doc->schema) > 1) {
             throw new Exception("You cannot use more than one schema in mysql5 without schema name prefixing\nPass the --useschemaprefix flag to turn this on");
         }
     }
     foreach ($db_doc->schema as $schema) {
         // database grants
         foreach ($schema->grant as $grant) {
             $ofs->write(mysql5_permission::get_permission_sql($db_doc, $schema, $schema, $grant) . "\n");
         }
         // enums
         foreach ($schema->type as $type) {
             $ofs->write(mysql5_type::get_creation_sql($schema, $type) . "\n");
         }
         // function definitions
         foreach ($schema->function as $function) {
             if (mysql5_function::has_definition($function)) {
                 $ofs->write(mysql5_function::get_creation_sql($schema, $function) . "\n\n");
             }
             // function grants
             foreach ($function->grant as $grant) {
                 $ofs->write(mysql5_permission::get_permission_sql($db_doc, $schema, $function, $grant) . "\n");
             }
         }
         $sequences = array();
         $triggers = array();
         // create defined tables
         foreach ($schema->table as $table) {
             // get sequences and triggers needed to make this table work
             $sequences = array_merge($sequences, mysql5_table::get_sequences_needed($schema, $table));
             $triggers = array_merge($triggers, mysql5_table::get_triggers_needed($schema, $table));
             // table definition
             $ofs->write(mysql5_table::get_creation_sql($schema, $table) . "\n\n");
             // table indexes
             // mysql5_diff_indexes::diff_indexes_table($ofs, NULL, NULL, $schema, $table);
             // table grants
             if (isset($table->grant)) {
                 foreach ($table->grant as $grant) {
                     $ofs->write(mysql5_permission::get_permission_sql($db_doc, $schema, $table, $grant) . "\n");
                 }
             }
             $ofs->write("\n");
         }
         // sequences contained in the schema + sequences used by serials
         $sequences = array_merge($sequences, dbx::to_array($schema->sequence));
         if (count($sequences) > 0) {
             $ofs->write(mysql5_sequence::get_shim_creation_sql() . "\n\n");
             $ofs->write(mysql5_sequence::get_creation_sql($schema, $sequences) . "\n\n");
             // sequence grants
             foreach ($sequences as $sequence) {
                 foreach ($sequence->grant as $grant) {
                     $ofs->write("-- grant for the {$sequence['name']} sequence applies to ALL sequences\n");
                     $ofs->write(mysql5_permission::get_permission_sql($db_doc, $schema, $sequence, $grant) . "\n");
                 }
             }
         }
         // trigger definitions + triggers used by serials
         $triggers = array_merge($triggers, dbx::to_array($schema->trigger));
         $unique_triggers = array();
         foreach ($triggers as $trigger) {
             // only do triggers set to the current sql format
             if (strcasecmp($trigger['sqlFormat'], dbsteward::get_sql_format()) == 0) {
                 // check that this table/timing/event combo hasn't been defined, because MySQL only
                 // allows one trigger per table per BEFORE/AFTER per action
                 $unique_name = "{$trigger['table']}-{$trigger['when']}-{$trigger['event']}";
                 if (array_key_exists($unique_name, $unique_triggers)) {
                     throw new Exception("MySQL will not allow trigger {$trigger['name']} to be created because it happens on the same table/timing/event as trigger {$unique_triggers[$unique_name]}");
                 }
                 $unique_triggers[$unique_name] = $trigger['name'];
                 $ofs->write(mysql5_trigger::get_creation_sql($schema, $trigger) . "\n");
             }
         }
     }
     foreach ($db_doc->schema as $schema) {
         // define table primary keys before foreign keys so unique requirements are always met for FOREIGN KEY constraints
         foreach ($schema->table as $table) {
             mysql5_diff_constraints::diff_constraints_table($ofs, NULL, NULL, $schema, $table, 'primaryKey', FALSE);
         }
         $ofs->write("\n");
     }
     // foreign key references
     // use the dependency order to specify foreign keys in an order that will satisfy nested foreign keys and etc
     for ($i = 0; $i < count($table_depends); $i++) {
         $dep_schema = $table_depends[$i]['schema'];
         $table = $table_depends[$i]['table'];
         if ($table['name'] === dbsteward::TABLE_DEPENDENCY_IGNORABLE_NAME) {
             // don't do anything with this table, it is a magic internal DBSteward value
             continue;
         }
         mysql5_diff_constraints::diff_constraints_table($ofs, NULL, NULL, $dep_schema, $table, 'constraint', FALSE);
     }
     $ofs->write("\n");
     mysql5_diff_views::create_views_ordered($ofs, null, $db_doc);
     // view permission grants
     foreach ($db_doc->schema as $schema) {
         foreach ($schema->view as $view) {
             if (isset($view->grant)) {
                 foreach ($view->grant as $grant) {
                     $ofs->write(mysql5_permission::get_permission_sql($db_doc, $schema, $view, $grant) . "\n");
                 }
             }
         }
     }
     // @TODO: database configurationParameter support
 }
 private function common($schema_xml, $obj = NULL, $expected)
 {
     $schema = new SimpleXMLElement($schema_xml);
     $node_obj = $obj ? $schema->{$obj} : $schema;
     $actual = mysql5_permission::get_permission_sql($this->dbdoc, $schema, $node_obj, $node_obj->grant);
     $this->assertEquals($expected, trim($actual));
 }