Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
henvic committed Dec 15, 2023
1 parent 0b7235e commit 575bd2b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 58 deletions.
43 changes: 20 additions & 23 deletions integration/users/create_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/FerretDB/FerretDB/internal/util/must"
"github.com/FerretDB/FerretDB/internal/util/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestCreateUser(t *testing.T) {
Expand Down Expand Up @@ -54,18 +55,9 @@ func TestCreateUser(t *testing.T) {
expected bson.D
skip string
}{
"MissingRoles": {
payload: bson.D{
{Key: "createUser", Value: "missing_roles"},
},
err: &mongo.CommandError{
Code: 40414,
Name: "Location40414",
Message: "BSON field 'createUser.roles' is missing but a required field",
},
skip: "not implemented yet", // TODO: implement for FerretDB
},
"AlreadyExists": {
skip: "TODO", // FIXME

payload: bson.D{
{Key: "createUser", Value: "should_already_exist"},
{Key: "roles", Value: bson.A{}},
Expand All @@ -78,6 +70,8 @@ func TestCreateUser(t *testing.T) {
},
},
"MissingPwdOrExternal": {
skip: "TODO", // FIXME

payload: bson.D{
{Key: "createUser", Value: "mising_pwd_or_external"},
{Key: "roles", Value: bson.A{}},
Expand All @@ -101,6 +95,8 @@ func TestCreateUser(t *testing.T) {
},
},
"WithComment": {
skip: "TODO", // FIXME

payload: bson.D{
{Key: "createUser", Value: "with_comment_user"},
{Key: "roles", Value: bson.A{}},
Expand All @@ -114,6 +110,8 @@ func TestCreateUser(t *testing.T) {
},
},
"WithCommentComposite": {
skip: "TODO", // FIXME

payload: bson.D{
{Key: "createUser", Value: "with_comment_composite"},
{Key: "roles", Value: bson.A{}},
Expand Down Expand Up @@ -144,21 +142,25 @@ func TestCreateUser(t *testing.T) {
if tc.skip != "" {
t.Skip(tc.skip)
}

t.Parallel()

var res bson.D
err := db.RunCommand(ctx, tc.payload).Decode(&res)
if tc.err != nil {
integration.AssertEqualAltCommandError(t, *tc.err, tc.altMessage, err)
return
}

require.NoError(t, err)

actual := integration.ConvertDocument(t, res)
actual.Remove("$clusterTime")
actual.Remove("operationTime")

expected := integration.ConvertDocument(t, tc.expected)
testutil.AssertEqual(t, expected, actual)
assert.NoError(t, err)

payload := integration.ConvertDocument(t, tc.payload)
assertUserExists(ctx, t, db, payload)
})
Expand All @@ -167,20 +169,15 @@ func TestCreateUser(t *testing.T) {

func assertUserExists(ctx context.Context, t testing.TB, db *mongo.Database, payload *types.Document) {
t.Helper()
var rec bson.D
err := db.Collection("system.users").FindOne(ctx, bson.D{
{Key: "user", Value: must.NotFail(payload.Get("createUser"))},
}).Decode(&rec)
assert.NoError(t, err)

var x any
t.Error(db.ListCollections(ctx, x))
t.Error(rec)
err = db.Collection("system.users").FindOne(ctx, bson.D{}).Decode(&rec)
assert.NoError(t, err)
var rec bson.D
err := db.Collection("system.users").FindOne(ctx, bson.D{{"user", must.NotFail(payload.Get("createUser"))}}).Decode(&rec)
require.NoError(t, err)

actualRecorded := integration.ConvertDocument(t, rec)
expectedRec := integration.ConvertDocument(t, bson.D{{Key: "ok", Value: float64(1)}})
expectedRec := integration.ConvertDocument(t, bson.D{
{"user", must.NotFail(payload.Get("createUser"))},
}) // FIXME

testutil.AssertEqual(t, expectedRec, actualRecorded)
// TODO compare other data
Expand Down
67 changes: 33 additions & 34 deletions internal/handler/msg_createuser.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ package handler
import (
"context"

"github.com/google/uuid"

"github.com/FerretDB/FerretDB/internal/backends"
"github.com/FerretDB/FerretDB/internal/handler/common"
"github.com/FerretDB/FerretDB/internal/handler/handlererrors"
"github.com/FerretDB/FerretDB/internal/types"
"github.com/FerretDB/FerretDB/internal/util/lazyerrors"
"github.com/FerretDB/FerretDB/internal/util/must"
Expand All @@ -33,61 +34,59 @@ func (h *Handler) MsgCreateUser(ctx context.Context, msg *wire.OpMsg) (*wire.OpM
return nil, lazyerrors.Error(err)
}

dbName, err := common.GetRequiredParam[string](document, "$db")
if err != nil {
return nil, err
}

// https://www.mongodb.com/docs/manual/reference/command/createUser/

username, err := common.GetRequiredParam[string](document, document.Command())
if err != nil {
return nil, err
}

_, err = common.GetOptionalParam[string](document, "pwd", "")
if err != nil {
if err := common.UnimplementedNonDefault(document, "customData", func(v any) bool {
if v == nil || v == types.Null {
return true
}

cd, ok := v.(*types.Document)
return ok && cd.Len() == 0
}); err != nil {
return nil, err
}

if err := common.UnimplementedNonDefault(document, "roles", func(v any) bool {
if v == nil || v == types.Null {
return true
}

roles, ok := v.(*types.Array)
return ok && roles.Len() == 0
}); err != nil {
return nil, err
}

common.Ignored(document, h.L, "roles", "writeConcern", "authenticationRestrictions", "mechanisms")

saved := must.NotFail(types.NewDocument(
"user", username,
"roles", must.NotFail(types.NewArray()), // Non-default value is currently ignored.
"pwd", "password", // TODO: hash the password.
))

if document.Has("customData") {
customData, err := common.GetOptionalParam[*types.Document](document, "customData", nil)
if err != nil {
return nil, err
}
saved.Set("customData", customData)
}

if document.Has("digestPassword") {
digestPassword, err := common.GetOptionalParam[bool](document, "digestPassword", true)
if err != nil {
return nil, err
if err := common.UnimplementedNonDefault(document, "digestPassword", func(v any) bool {
if v == nil || v == types.Null {
return true
}
saved.Set("digestPassword", digestPassword)
}

if document.Has("comment") {
saved.Set("comment", must.NotFail(document.Get("comment")))
}

dbName, err := common.GetRequiredParam[string](document, "$db")
if err != nil {
dp, ok := v.(bool)
return ok && dp
}); err != nil {
return nil, err
}

if dbName != "$external" && !document.Has("pwd") {
return nil, handlererrors.NewCommandErrorMsg(handlererrors.ErrBadValue, "Must provide a 'pwd' field for all user documents, except those with '$external' as the user's source db")
}
common.Ignored(document, h.L, "pwd", "writeConcern", "authenticationRestrictions", "mechanisms", "comment")

saved := must.NotFail(types.NewDocument(
"_id", dbName+"."+username,
"userID", types.Binary{Subtype: types.BinaryUUID, B: []byte(uuid.NewString())},
"user", username,
"credentials", types.MakeDocument(0),
))

db, err := h.b.Database(dbName)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Related [issue](https://github.com/FerretDB/FerretDB/issues/78).

| Command | Argument | Status | Comments |
| -------------------------- | -------------------------------- | ------ | --------------------------------------------------------- |
| `createUser` | | | [Issue](https://github.com/FerretDB/FerretDB/issues/1491) |
| `createUser` | | | [Issue](https://github.com/FerretDB/FerretDB/issues/1491) |
| | `pwd` | ⚠️ | |
| | `customData` | ⚠️ | |
| | `roles` | ⚠️ | |
Expand Down

0 comments on commit 575bd2b

Please sign in to comment.