github.com/dolthub/go-mysql-server@v0.18.0/sql/mysql_db/user_table.go (about)

     1  // Copyright 2021-2022 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package mysql_db
    16  
    17  import (
    18  	"fmt"
    19  	"sync"
    20  	"time"
    21  
    22  	"github.com/dolthub/go-mysql-server/sql"
    23  	"github.com/dolthub/go-mysql-server/sql/expression"
    24  	"github.com/dolthub/go-mysql-server/sql/in_mem_table"
    25  	"github.com/dolthub/go-mysql-server/sql/types"
    26  
    27  	"github.com/dolthub/vitess/go/sqltypes"
    28  )
    29  
    30  const userTblName = "user"
    31  
    32  var (
    33  	errUserPkEntry = fmt.Errorf("the primary key for the `user` table was given an unknown entry")
    34  	errUserPkRow   = fmt.Errorf("the primary key for the `user` table was given a row belonging to an unknown schema")
    35  	errUserSkEntry = fmt.Errorf("the secondary key for the `user` table was given an unknown entry")
    36  	errUserSkRow   = fmt.Errorf("the secondary key for the `user` table was given a row belonging to an unknown schema")
    37  
    38  	userTblSchema sql.Schema
    39  )
    40  
    41  // UserPrimaryKey is a key that represents the primary key for the "user" Grant Table.
    42  type UserPrimaryKey struct {
    43  	Host string
    44  	User string
    45  }
    46  
    47  type UserPrimaryKeyer struct{}
    48  
    49  var _ in_mem_table.Keyer[*User] = UserPrimaryKeyer{}
    50  
    51  func (UserPrimaryKeyer) GetKey(u *User) any {
    52  	return UserPrimaryKey{
    53  		Host: u.Host,
    54  		User: u.User,
    55  	}
    56  }
    57  
    58  // UserSecondaryKey is a key that represents the secondary key for the "user" Grant Table, which contains only usernames.
    59  type UserSecondaryKey struct {
    60  	User string
    61  }
    62  
    63  type UserSecondaryKeyer struct{}
    64  
    65  var _ in_mem_table.Keyer[*User] = UserSecondaryKeyer{}
    66  
    67  func (UserSecondaryKeyer) GetKey(u *User) any {
    68  	return UserSecondaryKey{
    69  		User: u.User,
    70  	}
    71  }
    72  
    73  func NewUserIndexedSetTable(lock, rlock sync.Locker) (in_mem_table.IndexedSet[*User], *in_mem_table.IndexedSetTable[*User]) {
    74  	set := in_mem_table.NewIndexedSet[*User](UserEquals, []in_mem_table.Keyer[*User]{
    75  		UserPrimaryKeyer{},
    76  		UserSecondaryKeyer{},
    77  	})
    78  	table := in_mem_table.NewIndexedSetTable[*User](
    79  		userTblName,
    80  		userTblSchema,
    81  		sql.Collation_utf8mb3_bin,
    82  		set,
    83  		UserOps,
    84  		lock,
    85  		rlock,
    86  	)
    87  	return set, table
    88  }
    89  
    90  // init creates the schema for the "user" Grant Table.
    91  func init() {
    92  	// Types
    93  	char32_utf8_bin := types.MustCreateString(sqltypes.Char, 32, sql.Collation_utf8_bin)
    94  	char64_utf8_bin := types.MustCreateString(sqltypes.Char, 64, sql.Collation_utf8_bin)
    95  	char255_ascii_general_ci := types.MustCreateString(sqltypes.Char, 255, sql.Collation_ascii_general_ci)
    96  	enum_ANY_X509_SPECIFIED_utf8_general_ci := types.MustCreateEnumType([]string{"", "ANY", "X509", "SPECIFIED"}, sql.Collation_utf8_general_ci)
    97  	enum_N_Y_utf8_general_ci := types.MustCreateEnumType([]string{"N", "Y"}, sql.Collation_utf8_general_ci)
    98  	text_utf8_bin := types.CreateText(sql.Collation_utf8_bin)
    99  
   100  	// Column Templates
   101  	blob_not_null_default_empty := &sql.Column{
   102  		Type:     types.Blob,
   103  		Default:  mustDefault(expression.NewLiteral("", types.Blob), types.Blob, true, false),
   104  		Nullable: false,
   105  	}
   106  	char32_utf8_bin_not_null_default_empty := &sql.Column{
   107  		Type:     char32_utf8_bin,
   108  		Default:  mustDefault(expression.NewLiteral("", char32_utf8_bin), char32_utf8_bin, true, false),
   109  		Nullable: false,
   110  	}
   111  	char64_utf8_bin_not_null_default_caching_sha2_password := &sql.Column{
   112  		Type:     char64_utf8_bin,
   113  		Default:  mustDefault(expression.NewLiteral("caching_sha2_password", char64_utf8_bin), char64_utf8_bin, true, false),
   114  		Nullable: false,
   115  	}
   116  	char255_ascii_general_ci_not_null_default_empty := &sql.Column{
   117  		Type:     char255_ascii_general_ci,
   118  		Default:  mustDefault(expression.NewLiteral("", char255_ascii_general_ci), char255_ascii_general_ci, true, false),
   119  		Nullable: false,
   120  	}
   121  	enum_ANY_X509_SPECIFIED_utf8_general_ci_not_null_default_empty := &sql.Column{
   122  		Type:     enum_ANY_X509_SPECIFIED_utf8_general_ci,
   123  		Default:  mustDefault(expression.NewLiteral("", enum_ANY_X509_SPECIFIED_utf8_general_ci), enum_ANY_X509_SPECIFIED_utf8_general_ci, true, false),
   124  		Nullable: false,
   125  	}
   126  	enum_N_Y_utf8_general_ci_not_null_default_N := &sql.Column{
   127  		Type:     enum_N_Y_utf8_general_ci,
   128  		Default:  mustDefault(expression.NewLiteral("N", enum_N_Y_utf8_general_ci), enum_N_Y_utf8_general_ci, true, false),
   129  		Nullable: false,
   130  	}
   131  	enum_N_Y_utf8_general_ci_nullable_default_nil := &sql.Column{
   132  		Type:     enum_N_Y_utf8_general_ci,
   133  		Default:  nil,
   134  		Nullable: true,
   135  	}
   136  	int_unsigned_not_null_default_0 := &sql.Column{
   137  		Type:     types.Uint32,
   138  		Default:  mustDefault(expression.NewLiteral(uint32(0), types.Uint32), types.Uint32, true, false),
   139  		Nullable: false,
   140  	}
   141  	json_nullable_default_nil := &sql.Column{
   142  		Type:     types.JSON,
   143  		Default:  nil,
   144  		Nullable: true,
   145  	}
   146  	smallint_unsigned_nullable_default_nil := &sql.Column{
   147  		Type:     types.Uint16,
   148  		Default:  nil,
   149  		Nullable: true,
   150  	}
   151  	text_utf8_bin_nullable_default_empty := &sql.Column{
   152  		Type:     text_utf8_bin,
   153  		Default:  mustDefault(expression.NewLiteral("", text_utf8_bin), text_utf8_bin, true, false),
   154  		Nullable: true,
   155  	}
   156  	timestamp_nullable_default_nil := &sql.Column{
   157  		Type:     types.Timestamp,
   158  		Default:  nil,
   159  		Nullable: true,
   160  	}
   161  
   162  	userTblSchema = sql.Schema{
   163  		columnTemplate("Host", userTblName, true, char255_ascii_general_ci_not_null_default_empty),
   164  		columnTemplate("User", userTblName, true, char32_utf8_bin_not_null_default_empty),
   165  		columnTemplate("Select_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   166  		columnTemplate("Insert_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   167  		columnTemplate("Update_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   168  		columnTemplate("Delete_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   169  		columnTemplate("Create_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   170  		columnTemplate("Drop_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   171  		columnTemplate("Reload_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   172  		columnTemplate("Shutdown_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   173  		columnTemplate("Process_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   174  		columnTemplate("File_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   175  		columnTemplate("Grant_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   176  		columnTemplate("References_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   177  		columnTemplate("Index_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   178  		columnTemplate("Alter_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   179  		columnTemplate("Show_db_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   180  		columnTemplate("Super_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   181  		columnTemplate("Create_tmp_table_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   182  		columnTemplate("Lock_tables_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   183  		columnTemplate("Execute_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   184  		columnTemplate("Repl_slave_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   185  		columnTemplate("Repl_client_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   186  		columnTemplate("Create_view_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   187  		columnTemplate("Show_view_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   188  		columnTemplate("Create_routine_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   189  		columnTemplate("Alter_routine_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   190  		columnTemplate("Create_user_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   191  		columnTemplate("Event_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   192  		columnTemplate("Trigger_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   193  		columnTemplate("Create_tablespace_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   194  		columnTemplate("ssl_type", userTblName, false, enum_ANY_X509_SPECIFIED_utf8_general_ci_not_null_default_empty),
   195  		columnTemplate("ssl_cipher", userTblName, false, blob_not_null_default_empty),
   196  		columnTemplate("x509_issuer", userTblName, false, blob_not_null_default_empty),
   197  		columnTemplate("x509_subject", userTblName, false, blob_not_null_default_empty),
   198  		columnTemplate("max_questions", userTblName, false, int_unsigned_not_null_default_0),
   199  		columnTemplate("max_updates", userTblName, false, int_unsigned_not_null_default_0),
   200  		columnTemplate("max_connections", userTblName, false, int_unsigned_not_null_default_0),
   201  		columnTemplate("max_user_connections", userTblName, false, int_unsigned_not_null_default_0),
   202  		columnTemplate("plugin", userTblName, false, char64_utf8_bin_not_null_default_caching_sha2_password),
   203  		columnTemplate("authentication_string", userTblName, false, text_utf8_bin_nullable_default_empty),
   204  		columnTemplate("password_expired", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   205  		columnTemplate("password_last_changed", userTblName, false, timestamp_nullable_default_nil),
   206  		columnTemplate("password_lifetime", userTblName, false, smallint_unsigned_nullable_default_nil),
   207  		columnTemplate("account_locked", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   208  		columnTemplate("Create_role_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   209  		columnTemplate("Drop_role_priv", userTblName, false, enum_N_Y_utf8_general_ci_not_null_default_N),
   210  		columnTemplate("Password_reuse_history", userTblName, false, smallint_unsigned_nullable_default_nil),
   211  		columnTemplate("Password_reuse_time", userTblName, false, smallint_unsigned_nullable_default_nil),
   212  		columnTemplate("Password_require_current", userTblName, false, enum_N_Y_utf8_general_ci_nullable_default_nil),
   213  		columnTemplate("User_attributes", userTblName, false, json_nullable_default_nil),
   214  		columnTemplate("identity", userTblName, false, text_utf8_bin_nullable_default_empty),
   215  	}
   216  }
   217  
   218  func addSuperUser(ed *Editor, username string, host string, password string) {
   219  	ed.PutUser(&User{
   220  		User:                username,
   221  		Host:                host,
   222  		PrivilegeSet:        NewPrivilegeSetWithAllPrivileges(),
   223  		Plugin:              "mysql_native_password",
   224  		Password:            password,
   225  		PasswordLastChanged: time.Unix(1, 0).UTC(),
   226  		Locked:              false,
   227  		Attributes:          nil,
   228  		IsRole:              false,
   229  		IsSuperUser:         true,
   230  	})
   231  }
   232  
   233  // These represent the column indexes of the "user" Grant Table.
   234  const (
   235  	userTblColIndex_Host int = iota
   236  	userTblColIndex_User
   237  	userTblColIndex_Select_priv
   238  	userTblColIndex_Insert_priv
   239  	userTblColIndex_Update_priv
   240  	userTblColIndex_Delete_priv
   241  	userTblColIndex_Create_priv
   242  	userTblColIndex_Drop_priv
   243  	userTblColIndex_Reload_priv
   244  	userTblColIndex_Shutdown_priv
   245  	userTblColIndex_Process_priv
   246  	userTblColIndex_File_priv
   247  	userTblColIndex_Grant_priv
   248  	userTblColIndex_References_priv
   249  	userTblColIndex_Index_priv
   250  	userTblColIndex_Alter_priv
   251  	userTblColIndex_Show_db_priv
   252  	userTblColIndex_Super_priv
   253  	userTblColIndex_Create_tmp_table_priv
   254  	userTblColIndex_Lock_tables_priv
   255  	userTblColIndex_Execute_priv
   256  	userTblColIndex_Repl_slave_priv
   257  	userTblColIndex_Repl_client_priv
   258  	userTblColIndex_Create_view_priv
   259  	userTblColIndex_Show_view_priv
   260  	userTblColIndex_Create_routine_priv
   261  	userTblColIndex_Alter_routine_priv
   262  	userTblColIndex_Create_user_priv
   263  	userTblColIndex_Event_priv
   264  	userTblColIndex_Trigger_priv
   265  	userTblColIndex_Create_tablespace_priv
   266  	userTblColIndex_ssl_type
   267  	userTblColIndex_ssl_cipher
   268  	userTblColIndex_x509_issuer
   269  	userTblColIndex_x509_subject
   270  	userTblColIndex_max_questions
   271  	userTblColIndex_max_updates
   272  	userTblColIndex_max_connections
   273  	userTblColIndex_max_user_connections
   274  	userTblColIndex_plugin
   275  	userTblColIndex_authentication_string
   276  	userTblColIndex_password_expired
   277  	userTblColIndex_password_last_changed
   278  	userTblColIndex_password_lifetime
   279  	userTblColIndex_account_locked
   280  	userTblColIndex_Create_role_priv
   281  	userTblColIndex_Drop_role_priv
   282  	userTblColIndex_Password_reuse_history
   283  	userTblColIndex_Password_reuse_time
   284  	userTblColIndex_Password_require_current
   285  	userTblColIndex_User_attributes
   286  	userTblColIndex_identity
   287  )