Пример #1
0
    def work(self, files):
        try:
            if self.ctrl_be.target_version >= Version(5, 7, 10):
                self.importer.reset_schemas()
            else:
                location = download_server_install_script(self.ctrl_be)
              
                if location:
                    workbench_version_string = get_current_sys_version(None)
                    server_version_string = get_sys_version_from_script(location)
                    
                    maj, min, rel = [int(i) for i in workbench_version_string.split(".")]
                    workbench_version = Version(maj, min, rel)
                    maj, min, rel = [int(i) for i in server_version_string.split(".")]
                    server_version = Version(maj, min, rel)

                    if server_version >= workbench_version:
                        log_info("Installing sys schema supplied by the server: %s\n" % str(location))
                        self.install_scripts([(location, None)], "Installing server script")
                        return
                    else:
                        log_info("Server sys schema install script exists but it's outdated compared to the one supplied by Workbench...\n")
                        
                        
                log_info("Installing sys schema supplied by workbench\n")
                self.install_scripts(files, "Installing Workbench script")
        except Exception as e:
              log_error("Runtime error when installing the sys schema: %s\n" % str(e))
              self._worker_queue.put(e)
        
        # This makes the screen refresh
        self._worker_queue.put(None)      
Пример #2
0
    def install_helper(self):
        self.installer_panel = HelperInstallPanel(self._owner, self._main_view.editor, self._ctrl_be)
        self._content.add(self.installer_panel, 1, 2, 2, 3, 0)
        self._owner.relayout() # needed b/c of layout bug in Mac

        if self._ctrl_be.target_version >= Version(5, 7, 10):
            filechooser = FileChooser(mforms.OpenFile)
            filechooser.set_title("Specify the location of mysql_upgrade")
            if filechooser.run_modal():
                self.installer_panel.importer._upgrade_tool_path = filechooser.get_path()

        self.installer_panel.importer.set_password(self._ctrl_be.get_mysql_password())
        self.installer_panel.start()
Пример #3
0
    def save(self):
        queries = []
        if self.password != self.confirm_password:
            raise WBSecurityValidationError("The new password and its confirmation don't match. Please re-enter them.")

        # workaround for server bug with replication #14358854
        queries.append("use mysql")

        #if not self.username:
        #    raise WBSecurityValidationError("Username must not be blank")

        if not self.host:
            raise WBSecurityValidationError("Host name must not be blank")

        # check if username + host is duplicated
        if self.is_commited and (self.username != self._orig_username or self.host != self._orig_host):
            if (self.username, self.host) in self._owner.account_names:
                raise WBSecurityValidationError("The '%s' account already exists and cannot be saved." % (self.formatted_name()))
        elif not self.is_commited:
            if (self.username, self.host, True) in self._owner.account_names:
                raise WBSecurityValidationError("The '%s' account already exists and cannot be saved." % (self.formatted_name()))

        fields = {
            "old_user" : escape_sql_string(self._orig_username) if self._orig_username else self._orig_username,
            "old_host" : escape_sql_string(self._orig_host) if self._orig_host else self._orig_host,
            "user" : escape_sql_string(self.username) or "NULL",
            "host" : escape_sql_string(self.host) or "",
            "password" : escape_sql_string(self.password or ""),
            "auth_plugin" : escape_sql_string(self.auth_plugin) if self.auth_plugin else None,
            "auth_string" : escape_sql_string(self.auth_string) if self.auth_string else None
        }
  
        password_already_set = False
        if not self.is_commited:  # This is a new account
            if self.auth_plugin:
                if self.auth_string is None:
                    create_query = CREATE_USER_QUERY_PLUGIN
                elif self.auth_plugin == 'mysql_native_password':
                    if (self._owner.ctrl_be.target_version and self._owner.ctrl_be.target_version < Version(5, 7, 0)):
                        create_query = CREATE_USER_QUERY_PLUGIN
                    else:
                        create_query = CREATE_USER_QUERY_PLUGIN_AUTH_NATIVE
                elif self.auth_plugin == 'caching_sha2_password':
                    create_query = CREATE_USER_QUERY_PLUGIN_AUTH_CACHING
                else:
                    create_query = CREATE_USER_QUERY_PLUGIN_AUTH_STRING
            else:
                create_query = CREATE_USER_QUERY
                password_already_set = True
            queries[:0] = [ create_query % fields ]  # This query should be the first in the batch
                                                     # WARNING: Now the pwd is sent in clear text
        else:  # The account already exists

            assert self._orig_username is not None and self._orig_host is not None

            if self._orig_username != self.username or self._orig_host != self.host:  # Rename the user
                queries[:0] = [ RENAME_USER_QUERY % fields ]  # This query should be the first in the batch

        names = ["MAX_QUERIES_PER_HOUR", "MAX_UPDATES_PER_HOUR", "MAX_CONNECTIONS_PER_HOUR"] + (self._owner.has_max_user_connections and ["MAX_USER_CONNECTIONS"] or [])
        values = [str(s) for s in [self.max_questions, self.max_updates, self.max_connections] + (self._owner.has_max_user_connections and [self.max_user_connections] or [])]
        account_limits = dict(zip(names, values))
        limits_changed = account_limits != self._orig_account_limits

        is_normal_priv =  lambda priv: ( PrivilegeInfo.get(priv, (None,None))[0] and 
                                         PrivilegeInfo.get(priv, (None,None))[0][0] != '*'
                                       )

        all_normal_privs = set( priv for priv in self._owner.global_privilege_names if is_normal_priv(priv) )
        new_granted_privs = (self._global_privs - self._orig_global_privs) & all_normal_privs
        orig_revoked_privs =  all_normal_privs - self._orig_global_privs
        new_revoked_privs = all_normal_privs - self._global_privs - orig_revoked_privs


        if new_granted_privs or limits_changed:
            if 'Grant_priv' in new_granted_privs:
                account_limits['GRANT'] = 'OPTION'
                new_granted_privs.remove('Grant_priv')
            if (all_normal_privs - new_granted_privs) <= set(['Grant_priv']):
                priv_list = ['ALL PRIVILEGES']
            else:
                priv_list = [ PrivilegeInfo[priv][0] for priv in new_granted_privs ]
            fields['granted_privs'] = ', '.join(priv_list) or 'USAGE'
            grant_query = GRANT_GLOBAL_PRIVILEGES_QUERY % fields

            with_clause = ''
            for key, value in account_limits.iteritems(): #name, value in zip(names, values):
                if value != self._orig_account_limits.get(key):
                    if key == "GRANT" and value == "OPTION":
                        queries.append(grant_query + "WITH GRANT OPTION")
                        continue
                    if not with_clause:
                        with_clause = ' WITH '
                    with_clause += "%s %s "%(key, value)
                    
            if self._owner.ctrl_be.target_version and self._owner.ctrl_be.target_version >= Version(8, 0, 5):
                queries.append(grant_query)
                queries.append((ALTER_USER_RESOURCES % fields) + with_clause)
            else:
                queries.append(grant_query + with_clause)

        if new_revoked_privs:
            if all_normal_privs - new_revoked_privs: #set(self._owner.global_privilege_names) - revoked_privs_set:  # Revoke a subset of all privs
                priv_list = [ PrivilegeInfo[priv][0] for priv in new_revoked_privs ]
                fields['revoked_privs'] = ', '.join(priv_list)
                queries.append(REVOKE_GLOBAL_PRIVILEGES_QUERY % fields)
            else:  # All privs are to be revoked so use the revoke all query
                queries.append(REVOKE_ALL % fields)

        if self.password != self._orig_password and not password_already_set:
            change_pw = CHANGE_PASSWORD_QUERY if self._owner.ctrl_be.target_version and self._owner.ctrl_be.target_version < Version(5,7,6) else CHANGE_PASSWORD_QUERY_576
            blank_pw = BLANK_PASSWORD_QUERY if self._owner.ctrl_be.target_version and self._owner.ctrl_be.target_version < Version(5,7,6) else BLANK_PASSWORD_QUERY
            # special hack required by server to handle sha256 password accounts
            if self._owner.ctrl_be.target_version and self._owner.ctrl_be.target_version < Version(8, 0, 5):
                if self.auth_plugin == "sha256_password":
                    queries.append("SET old_passwords = 2")
                else:
                    queries.append("SET old_passwords = 0")
                    
            if fields["password"]:
                queries.append(change_pw % fields)
            else:
                queries.append(blank_pw % fields)

        action = "changing" if self.is_commited else "creating"
        for query in queries:
            try:
                self._owner.ctrl_be.exec_sql(query)
            except QueryError, e:
                if e.error == 1142:
                    raise Exception("Error %s account %s@%s: Insufficient rights to perform operation"%(action, self.username, self.host))
                else:
                    raise Exception("Error %s account %s@%s: %s"%(action, self.username, self.host, e.errortext or e))
            except Exception, e:
                raise Exception("Error %s account %s@%s: %s"%(action, self.username, self.host, e))
Пример #4
0
    def upgrade_password_format(self):
        queries = []
        if self.password != self.confirm_password:
            raise WBSecurityValidationError("The new password and its confirmation don't match. Please re-enter them.")

        queries.append("use mysql")

        if not self.host:
            raise WBSecurityValidationError("Host name must not be blank")

        fields = {
            "user" : escape_sql_string(self.username) or "NULL",
            "host" : escape_sql_string(self.host) or "",
            "password" : escape_sql_string(self.password or ""),
        }

        queries.append("SET old_passwords = 0")        
        if self._owner.ctrl_be.target_version and self._owner.ctrl_be.target_version.is_supported_mysql_version_at_least(5, 5, 7):
            queries.append("UPDATE mysql.user SET plugin = 'mysql_native_password' WHERE user = '******' AND host = '%(host)s'" % fields)
        queries.append("FLUSH PRIVILEGES")
        change_pw = CHANGE_PASSWORD_QUERY if self._owner.ctrl_be.target_version and self._owner.ctrl_be.target_version < Version(5,7,6) else CHANGE_PASSWORD_QUERY_576
        queries.append(change_pw % fields)
        queries.append("FLUSH PRIVILEGES")
        
        action = "changing"
        for query in queries:
            try:
                self._owner.ctrl_be.exec_sql(query)
            except QueryError, e:
                if e.error == 1142:
                    raise Exception("Error %s account %s@%s: Insufficient rights to perform operation"%(action, self.username, self.host))
                else:
                    raise Exception("Error %s account %s@%s: %s"%(action, self.username, self.host, e.errortext or e))
            except Exception, e:
                raise Exception("Error %s account %s@%s: %s"%(action, self.username, self.host, e))
Пример #5
0
            "MAX_QUERIES_PER_HOUR"      : str(self.max_questions),
            "MAX_UPDATES_PER_HOUR"      : str(self.max_updates),
            "MAX_CONNECTIONS_PER_HOUR"  : str(self.max_connections),
                                    }
        if self._owner.has_max_user_connections:
            self.max_user_connections = result.intByName("max_user_connections")
            self._orig_account_limits["MAX_USER_CONNECTIONS"] = str(self.max_user_connections)
        if self._owner.has_plugin:
            self.auth_plugin = result.stringByName("plugin")
        if self._owner.has_authentication_string:
            self.auth_string = result.stringByName("authentication_string")
        self.password_expired = False
        if self._owner.has_password_expired:
            self.password_expired = result.stringByName("password_expired") == 'Y'

        password_column = 'password' if self._owner.ctrl_be.target_version and self._owner.ctrl_be.target_version < Version(5,7,6) else 'authentication_string'
        self.old_authentication = len(result.stringByName(password_column)) == 16
        self.blank_password = len(result.stringByName(password_column)) == 0

        self._global_privs = set()
        for priv in self._owner.global_privilege_names:
            if result.stringByName(priv) == 'Y':
                self._global_privs.add(priv)

        self.forget_custom_privs()

        """ not necessary, IS is accessible to all
        # privs from information_schema tables
        query = GET_ACCOUNT_IS_TABLE_PRIVS_QUERY % {"user":username,"host":hostname}
        result = modules.DbMySQLQuery.executeQuery(self._owner._connection, query)
        if result < 0:
    def setup_info_table(self, info_table, info, params):
        info_table.set_row_count(len(info) + 1)
        for i, item in enumerate(info):
            (label, value_source) = item
            if callable(value_source):
                value = value_source(*params)
            else:
                value = value_source

            if self.controls.has_key(label):
                info_table.remove(self.controls[label][0])
            else:
                l = mforms.newLabel(label + ":")
                l.set_name(label)
                info_table.add(l, 0, 1, i, i + 1,
                               mforms.VFillFlag | mforms.HFillFlag)
            is_gtid_mode_setable = label == 'GTID Mode:' and self.ctrl_be.target_version >= Version(
                5, 7, 6)
            if type(value) is bool or value is None:
                b = StateIcon()
                if label and label != '':
                    b.set_name(label + " Value")
                b.set_state(value)
                info_table.add(
                    b, 1, 2, i, i + 1,
                    mforms.HFillFlag | mforms.HExpandFlag | mforms.VFillFlag)
                self.controls[label] = (b, value_source)
            elif type(value) is tuple:
                b = StateIcon()
                if label and label != '':
                    b.set_name(label + " Value")
                b.set_state(value[0])
                if value[0] and value[1]:
                    b.set_text(value[1])
                info_table.add(
                    b, 1, 2, i, i + 1,
                    mforms.HFillFlag | mforms.HExpandFlag | mforms.VFillFlag)
                self.controls[label] = (b, value_source)
            else:
                if is_gtid_mode_setable:
                    self.gtid_mode_selector = mforms.newSelector()
                    if label and label != '':
                        self.gtid_mode_selector.set_name(label + " Value")
                    self.gtid_mode_selector.add_items(
                        ["OFF", "UPGRADE_STEP_1", "UPGRADE_STEP_1", "ON"])
                    self.gtid_mode_selector.set_selected(
                        self.gtid_mode_selector.index_of_item_with_title(
                            value_source))
                    self.gtid_mode_selector.add_changed_callback(
                        self._gtid_mode_changed)
                    info_table.add(
                        self.gtid_mode_selector, 1, 2, i, i + 1,
                        mforms.HFillFlag | mforms.HExpandFlag
                        | mforms.VFillFlag)
                    self.controls[label] = (self.gtid_mode_selector,
                                            value_source)
                else:
                    l2 = mforms.newLabel(value or "")
                    if label and label != '':
                        l2.set_name(label + " Value")
                    l2.set_style(mforms.BoldStyle)
                    info_table.add(
                        l2, 1, 2, i, i + 1, mforms.HFillFlag
                        | mforms.HExpandFlag | mforms.VFillFlag)
                    self.controls[label] = (l2, value_source)
        info_table.add(mforms.newLabel(""), 0, 1, len(info),
                       len(info) + 1, mforms.HFillFlag)  # blank space
        return info_table
Пример #7
0
    def __init__(self, owner, json_text, context, server_version):
        mforms.Box.__init__(self, False)
        self.set_managed()
        self.set_release_on_add()

        self._context = context

        get_resource_path = mforms.App.get().get_resource_path

        self.toolbar = mforms.newToolBar(mforms.SecondaryToolBar)
        self.toolbar.set_back_color("#ffffff")

        self.switcher_item = newToolBarItem(mforms.SelectorItem)
        self.toolbar.add_item(self.switcher_item)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        l = newToolBarItem(mforms.LabelItem)
        l.set_text("Display Info:")
        self.toolbar.add_item(l)

        item = newToolBarItem(mforms.SelectorItem)
        item.set_selector_items(["Read + Eval cost", "Data Read per Join"])
        item.add_activated_callback(self.display_cost)
        self.toolbar.add_item(item)
        cost_type_item = item

        # cost info was added in 5.7.2
        has_cost_info = server_version >= Version(5, 7)
        if not has_cost_info:
            item.set_enabled(False)


#item = newToolBarItem(mforms.SelectorItem)
#        item.set_selector_items(["Show Aggregated Costs", "Show Individual Costs"])
#        item.add_activated_callback(self.toggle_aggregated)
#        self.toolbar.add_item(item)

#btn = newToolBarItem(mforms.SegmentedToggleItem)
#btn.set_icon(get_resource_path("qe_resultset-tb-switcher_grid_off_mac.png"))
#btn.set_alt_icon(get_resource_path("qe_resultset-tb-switcher_grid_on_mac.png"))
#self.toolbar.add_item(btn)

#btn = newToolBarItem(mforms.SegmentedToggleItem)
#btn.set_icon(get_resource_path("qe_resultset-tb-switcher_explain_off.png"))
#btn.set_alt_icon(get_resource_path("qe_resultset-tb-switcher_explain_on.png"))
#self.toolbar.add_item(btn)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        btn = newToolBarItem(mforms.ActionItem)
        btn.set_icon(get_resource_path("tiny_saveas.png"))
        btn.add_activated_callback(self.save)
        btn.set_tooltip("Save image to an external file.")
        self.toolbar.add_item(btn)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        l = newToolBarItem(mforms.LabelItem)
        l.set_text("Overview:")
        self.toolbar.add_item(l)

        btn = newToolBarItem(mforms.ActionItem)
        btn.set_icon(
            get_resource_path("qe_sql-editor-explain-tb-overview.png"))
        btn.add_activated_callback(self.overview)
        btn.set_tooltip("Zoom out the diagram.")
        self.toolbar.add_item(btn)

        s = newToolBarItem(mforms.SeparatorItem)
        self.toolbar.add_item(s)

        l = newToolBarItem(mforms.LabelItem)
        l.set_text("View Source:")
        self.toolbar.add_item(l)

        btn = newToolBarItem(mforms.ToggleItem)
        btn.set_icon(get_resource_path("statusbar_output.png"))
        btn.set_alt_icon(get_resource_path("statusbar_output.png"))
        btn.add_activated_callback(self.switch_to_raw)
        btn.set_tooltip("View the raw JSON explain data.")
        self.toolbar.add_item(btn)

        self.add(self.toolbar, False, True)

        # Query Plan diagram
        self.scroll = mforms.newScrollPanel(mforms.ScrollPanelNoFlags)
        self.scroll.set_visible_scrollers(True, True)

        #self.img = mforms.newImageBox()
        self.drawbox = RenderBox(self._context, self.scroll)
        self.scroll.add(self.drawbox)

        self.drawbox.node_spacing = self.node_spacing
        self.drawbox.vertical = self.vertical
        self.add(self.scroll, True, True)

        self.display_cost(cost_type_item)

        # textbox to view the json data
        self._raw_explain = mforms.CodeEditor()
        self._raw_explain.set_value(json_text)
        self._raw_explain.set_language(mforms.LanguageJson)
        self._raw_explain.set_features(
            mforms.FeatureReadOnly | mforms.FeatureFolding, True)
        self.add(self._raw_explain, True, True)
        self._raw_explain.show(False)

        nc.add_observer(self.updateColors, "GNColorsChanged")
        backgroundColor = Color.getSystemColor(TextBackgroundColor)
        self.scroll.set_back_color(backgroundColor.to_html())