Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stubs for authentication commands #3776

Merged
merged 11 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ labels:
- name: area/aggregations
color: "#5319E7"
description: Issues about aggregation pipelines
- name: area/auth
color: "#E4012C"
description: Issues about authentication
- name: area/build
color: "#52D58A"
description: Issues about builds and CI
Expand Down
2 changes: 2 additions & 0 deletions cmd/ferretdb/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ var cli struct {

DisableFilterPushdown bool `default:"false" help:"Experimental: disable filter pushdown."`
EnableOplog bool `default:"false" help:"Experimental: enable capped collections, tailable cursors and OpLog." hidden:""`
EnableNewAuth bool `default:"false" help:"Experimental: enable new authentication." hidden:""`

//nolint:lll // for readability
Telemetry struct {
Expand Down Expand Up @@ -397,6 +398,7 @@ func run() {
TestOpts: registry.TestOpts{
DisableFilterPushdown: cli.Test.DisableFilterPushdown,
EnableOplog: cli.Test.EnableOplog,
EnableNewAuth: cli.Test.EnableNewAuth,
},
})
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions integration/setup/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ func setupListener(tb testtb.TB, ctx context.Context, logger *zap.Logger) string
TestOpts: registry.TestOpts{
DisableFilterPushdown: *disableFilterPushdownF,
EnableOplog: true,
EnableNewAuth: false,
},
}
h, closeBackend, err := registry.NewHandler(handler, handlerOpts)
Expand Down
4 changes: 2 additions & 2 deletions internal/clientconn/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -560,15 +560,15 @@ func (c *conn) route(ctx context.Context, reqHeader *wire.MsgHeader, reqBody wir
//
// The passed context is canceled when the client disconnects.
func (c *conn) handleOpMsg(ctx context.Context, msg *wire.OpMsg, command string) (*wire.OpMsg, error) {
if cmd, ok := handler.Commands[command]; ok {
if cmd, ok := c.h.Commands()[command]; ok {
if cmd.Handler != nil {
defer observability.FuncCall(ctx)()

defer pprof.SetGoroutineLabels(ctx)
ctx = pprof.WithLabels(ctx, pprof.Labels("command", command))
pprof.SetGoroutineLabels(ctx)

return cmd.Handler(c.h, ctx, msg)
return cmd.Handler(ctx, msg)
}
}

Expand Down
264 changes: 264 additions & 0 deletions internal/handler/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
// Copyright 2021 FerretDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package handler

import (
"context"

"github.com/FerretDB/FerretDB/internal/wire"
)

// command represents a handler for single command.
type command struct {
// Handler processes this command.
//
// The passed context is canceled when the client disconnects.
Handler func(context.Context, *wire.OpMsg) (*wire.OpMsg, error)

// Help is shown in the `listCommands` command output.
// If empty, that command is hidden, but still can be used.
Help string
}

// initCommands initializes the commands map for that handler instance.
func (h *Handler) initCommands() {
h.commands = map[string]command{
// sorted alphabetically
"aggregate": {
Handler: h.MsgAggregate,
Help: "Returns aggregated data.",
},
"buildInfo": {
Handler: h.MsgBuildInfo,
Help: "Returns a summary of the build information.",
},
"buildinfo": { // old lowercase variant
Handler: h.MsgBuildInfo,
Help: "", // hidden
},
"collMod": {
Handler: h.MsgCollMod,
Help: "Adds options to a collection or modify view definitions.",
},
"collStats": {
Handler: h.MsgCollStats,
Help: "Returns storage data for a collection.",
},
"compact": {
Handler: h.MsgCompact,
Help: "Reduces the disk space collection takes and refreshes its statistics.",
},
"connectionStatus": {
Handler: h.MsgConnectionStatus,
Help: "Returns information about the current connection, " +
"specifically the state of authenticated users and their available permissions.",
},
"count": {
Handler: h.MsgCount,
Help: "Returns the count of documents that's matched by the query.",
},
"create": {
Handler: h.MsgCreate,
Help: "Creates the collection.",
},
"createIndexes": {
Handler: h.MsgCreateIndexes,
Help: "Creates indexes on a collection.",
},
"currentOp": {
Handler: h.MsgCurrentOp,
Help: "Returns information about operations currently in progress.",
},
"dataSize": {
Handler: h.MsgDataSize,
Help: "Returns the size of the collection in bytes.",
},
"dbStats": {
Handler: h.MsgDBStats,
Help: "Returns the statistics of the database.",
},
"dbstats": { // old lowercase variant
Handler: h.MsgDBStats,
Help: "", // hidden
},
"debugError": {
Handler: h.MsgDebugError,
Help: "Returns error for debugging.",
},
"delete": {
Handler: h.MsgDelete,
Help: "Deletes documents matched by the query.",
},
"distinct": {
Handler: h.MsgDistinct,
Help: "Returns an array of distinct values for the given field.",
},
"drop": {
Handler: h.MsgDrop,
Help: "Drops the collection.",
},
"dropDatabase": {
Handler: h.MsgDropDatabase,
Help: "Drops production database.",
},
"dropIndexes": {
Handler: h.MsgDropIndexes,
Help: "Drops indexes on a collection.",
},
"explain": {
Handler: h.MsgExplain,
Help: "Returns the execution plan.",
},
"find": {
Handler: h.MsgFind,
Help: "Returns documents matched by the query.",
},
"findAndModify": {
Handler: h.MsgFindAndModify,
Help: "Updates or deletes, and returns a document matched by the query.",
},
"findandmodify": { // old lowercase variant
Handler: h.MsgFindAndModify,
Help: "", // hidden
},
"getCmdLineOpts": {
Handler: h.MsgGetCmdLineOpts,
Help: "Returns a summary of all runtime and configuration options.",
},
"getFreeMonitoringStatus": {
Handler: h.MsgGetFreeMonitoringStatus,
Help: "Returns a status of the free monitoring.",
},
"getLog": {
Handler: h.MsgGetLog,
Help: "Returns the most recent logged events from memory.",
},
"getMore": {
Handler: h.MsgGetMore,
Help: "Returns the next batch of documents from a cursor.",
},
"getParameter": {
Handler: h.MsgGetParameter,
Help: "Returns the value of the parameter.",
},
"hello": {
Handler: h.MsgHello,
Help: "Returns the role of the FerretDB instance.",
},
"hostInfo": {
Handler: h.MsgHostInfo,
Help: "Returns a summary of the system information.",
},
"insert": {
Handler: h.MsgInsert,
Help: "Inserts documents into the database.",
},
"isMaster": {
Handler: h.MsgIsMaster,
Help: "Returns the role of the FerretDB instance.",
},
"ismaster": { // old lowercase variant
Handler: h.MsgIsMaster,
Help: "", // hidden
},
"killCursors": {
Handler: h.MsgKillCursors,
Help: "Closes server cursors.",
},
"listCollections": {
Handler: h.MsgListCollections,
Help: "Returns the information of the collections and views in the database.",
},
"listCommands": {
Handler: h.MsgListCommands,
Help: "Returns a list of currently supported commands.",
},
"listDatabases": {
Handler: h.MsgListDatabases,
Help: "Returns a summary of all the databases.",
},
"listIndexes": {
Handler: h.MsgListIndexes,
Help: "Returns a summary of indexes of the specified collection.",
},
"logout": {
Handler: h.MsgLogout,
Help: "Logs out from the current session.",
},
"ping": {
Handler: h.MsgPing,
Help: "Returns a pong response.",
},
"renameCollection": {
Handler: h.MsgRenameCollection,
Help: "Changes the name of an existing collection.",
},
"saslStart": {
Handler: h.MsgSASLStart,
Help: "Starts a SASL conversation.",
},
"serverStatus": {
Handler: h.MsgServerStatus,
Help: "Returns an overview of the databases state.",
},
"setFreeMonitoring": {
Handler: h.MsgSetFreeMonitoring,
Help: "Toggles free monitoring.",
},
"update": {
Handler: h.MsgUpdate,
Help: "Updates documents that are matched by the query.",
},
"validate": {
Handler: h.MsgValidate,
Help: "Validates collection.",
},
"whatsmyuri": {
Handler: h.MsgWhatsMyURI,
Help: "Returns peer information.",
},
// please keep sorted alphabetically
}

if h.EnableNewAuth {
// sorted alphabetically
h.commands["createUser"] = command{
Handler: h.MsgCreateUser,
Help: "Creates a new user.",
}
h.commands["dropAllUsersFromDatabase"] = command{
Handler: h.MsgDropAllUsersFromDatabase,
Help: "Drops all user from database.",
}
h.commands["dropUser"] = command{
Handler: h.MsgDropUser,
Help: "Drops user.",
}
h.commands["updateUser"] = command{
Handler: h.MsgUpdateUser,
Help: "Updates user.",
}
h.commands["usersInfo"] = command{
Handler: h.MsgUpdateUser,
Help: "Returns information about users.",
}
// please keep sorted alphabetically
}

Check warning on line 258 in internal/handler/commands.go

View check run for this annotation

Codecov / codecov/patch

internal/handler/commands.go#L236-L258

Added lines #L236 - L258 were not covered by tests
}

// Commands returns a map of enabled commands.
func (h *Handler) Commands() map[string]command {
return h.commands
}
15 changes: 10 additions & 5 deletions internal/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ import (
// MsgXXX methods handle OP_MSG commands.
// CmdQuery handles a limited subset of OP_QUERY messages.
//
// Handler is shared between all connections! Be careful when you need connection-specific information.
// Currently, we pass connection information through context, see `ConnInfo` and its usage.
// Handler instance is shared between all client connections.
type Handler struct {
*NewOpts

b backends.Backend

cursors *cursor.Registry
cursors *cursor.Registry
commands map[string]command
}

// NewOpts represents handler configuration.
Expand All @@ -54,6 +54,7 @@ type NewOpts struct {
// test options
DisableFilterPushdown bool
EnableOplog bool
EnableNewAuth bool
}

// New returns a new handler.
Expand All @@ -64,11 +65,15 @@ func New(opts *NewOpts) (*Handler, error) {
b = oplog.NewBackend(b, opts.L.Named("oplog"))
}

return &Handler{
h := &Handler{
b: b,
NewOpts: opts,
cursors: cursor.NewRegistry(opts.L.Named("cursors")),
}, nil
}

h.initCommands()

return h, nil
}

// Close gracefully shutdowns handler.
Expand Down
34 changes: 34 additions & 0 deletions internal/handler/msg_createuser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2021 FerretDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package handler

import (
"context"

"github.com/FerretDB/FerretDB/internal/handler/common"
"github.com/FerretDB/FerretDB/internal/util/lazyerrors"
"github.com/FerretDB/FerretDB/internal/wire"
)

// MsgCreateUser implements `createUser` command.
func (h *Handler) MsgCreateUser(ctx context.Context, msg *wire.OpMsg) (*wire.OpMsg, error) {
document, err := msg.Document()
if err != nil {
return nil, lazyerrors.Error(err)
}

Check warning on line 30 in internal/handler/msg_createuser.go

View check run for this annotation

Codecov / codecov/patch

internal/handler/msg_createuser.go#L26-L30

Added lines #L26 - L30 were not covered by tests

// TODO https://github.com/FerretDB/FerretDB/issues/1491
return nil, common.Unimplemented(document, document.Command())

Check warning on line 33 in internal/handler/msg_createuser.go

View check run for this annotation

Codecov / codecov/patch

internal/handler/msg_createuser.go#L33

Added line #L33 was not covered by tests
}
Loading
Loading