From 7c75b27c8d14c9f3a289e942d3d145a89df9d152 Mon Sep 17 00:00:00 2001 From: Henry <111202+cryptix@users.noreply.github.com> Date: Mon, 10 May 2021 13:51:05 +0200 Subject: [PATCH] have a clear error on taken aliases fixes #194 --- muxrpc/handlers/alias/handler.go | 5 ++++ muxrpc/test/go/alias_test.go | 9 +++++++ roomdb/sqlite/aliases.go | 6 ++++- roomdb/sqlite/aliases_test.go | 41 +++++++++++++++++++++++++++++++- roomdb/types.go | 8 +++++++ 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/muxrpc/handlers/alias/handler.go b/muxrpc/handlers/alias/handler.go index a63c30c..07a20bd 100644 --- a/muxrpc/handlers/alias/handler.go +++ b/muxrpc/handlers/alias/handler.go @@ -7,6 +7,7 @@ import ( "context" "encoding/base64" "encoding/json" + "errors" "fmt" "strings" @@ -99,6 +100,10 @@ func (h Handler) Register(ctx context.Context, req *muxrpc.Request) (interface{} err = h.db.Register(ctx, confirmation.Alias, confirmation.UserID, confirmation.Signature) if err != nil { + var takenErr roomdb.ErrAliasTaken + if errors.As(err, &takenErr) { + return nil, takenErr + } return nil, fmt.Errorf("registerAlias: could not register alias: %w", err) } diff --git a/muxrpc/test/go/alias_test.go b/muxrpc/test/go/alias_test.go index e6a4d22..1180db3 100644 --- a/muxrpc/test/go/alias_test.go +++ b/muxrpc/test/go/alias_test.go @@ -6,6 +6,7 @@ import ( "context" "crypto/rand" "encoding/base64" + "errors" "net/url" "testing" "time" @@ -105,6 +106,14 @@ func TestAliasRegister(t *testing.T) { t.Log("alias stored") + // check taken error + err = clientForServer.Async(ctx, ®isterResponse, muxrpc.TypeString, muxrpc.Method{"room", "registerAlias"}, "bob", sig) + r.Error(err) + + var callErr *muxrpc.CallError + r.True(errors.As(err, &callErr), "expected a call error: %T", err) + r.Equal(`alias ("bob") is already taken`, callErr.Message) + for _, bot := range theBots { bot.srv.Shutdown() r.NoError(bot.srv.Close()) diff --git a/roomdb/sqlite/aliases.go b/roomdb/sqlite/aliases.go index 2446472..c50e958 100644 --- a/roomdb/sqlite/aliases.go +++ b/roomdb/sqlite/aliases.go @@ -7,6 +7,7 @@ import ( "database/sql" "github.com/friendsofgo/errors" + "github.com/mattn/go-sqlite3" "github.com/volatiletech/sqlboiler/v4/boil" "github.com/volatiletech/sqlboiler/v4/queries/qm" @@ -93,7 +94,10 @@ func (a Aliases) Register(ctx context.Context, alias string, userFeed refs.FeedR newEntry.Signature = signature err = newEntry.Insert(ctx, tx, boil.Infer()) - + var sqlErr sqlite3.Error + if errors.As(err, &sqlErr) && sqlErr.ExtendedCode == sqlite3.ErrConstraintUnique { + return roomdb.ErrAliasTaken{Name: alias} + } return err }) } diff --git a/roomdb/sqlite/aliases_test.go b/roomdb/sqlite/aliases_test.go index 708de2a..40ff6bb 100644 --- a/roomdb/sqlite/aliases_test.go +++ b/roomdb/sqlite/aliases_test.go @@ -71,7 +71,7 @@ func TestAliases(t *testing.T) { err = db.Aliases.Register(ctx, testName, newMember, testSig) r.NoError(err) - // should have one member now + // should have one alias now lst, err := db.Aliases.List(ctx) r.NoError(err) r.Len(lst, 1) @@ -97,3 +97,42 @@ func TestAliases(t *testing.T) { r.EqualError(err, roomdb.ErrNotFound.Error()) }) } + +func TestAliasesUniqueError(t *testing.T) { + r := require.New(t) + ctx := context.Background() + + testRepo := filepath.Join("testrun", t.Name()) + os.RemoveAll(testRepo) + tr := repo.New(testRepo) + + db, err := Open(tr) + r.NoError(err) + + // fake feed for testing, looks ok at least + newMember := refs.FeedRef{ID: bytes.Repeat([]byte("acab"), 8), Algo: refs.RefAlgoFeedSSB1} + + // 64 bytes of random for testing (validation is handled by the handlers) + testSig := make([]byte, 64) + rand.Read(testSig) + + testName := "thealias" + + // allow the member + _, err = db.Members.Add(ctx, newMember, roomdb.RoleMember) + r.NoError(err) + + err = db.Aliases.Register(ctx, testName, newMember, testSig) + r.NoError(err) + + // should have one alias now + lst, err := db.Aliases.List(ctx) + r.NoError(err) + r.Len(lst, 1) + + err = db.Aliases.Register(ctx, testName, newMember, testSig) + r.Error(err) + var takenErr roomdb.ErrAliasTaken + r.True(errors.As(err, &takenErr), "expected a special error value") + r.Equal(testName, takenErr.Name) +} diff --git a/roomdb/types.go b/roomdb/types.go index ebe55bf..e2870e2 100644 --- a/roomdb/types.go +++ b/roomdb/types.go @@ -26,6 +26,14 @@ type Alias struct { Signature []byte } +type ErrAliasTaken struct { + Name string +} + +func (e ErrAliasTaken) Error() string { + return fmt.Sprintf("alias (%q) is already taken", e.Name) +} + // Member holds all the information an internal user of the room has. type Member struct { ID int64