mirror of
https://github.com/1f349/dendrite.git
synced 2024-11-25 13:11:37 +00:00
Fix pg user already exists (#1076)
* Return newly created error if user already exists (#1002) Signed-off-by: Till Faelligen <tfaelligen@gmail.com> * Rename variable * Remove check for account and use returned error * Return ErrUserExists Signed-off-by: Till Faelligen <tfaelligen@gmail.com> * State that CreateAccount will return err ErrUserExists if the user exists Signed-off-by: Till Faelligen <tfaelligen@gmail.com> * Also check sqlite for constraint error * Revert "Also check sqlite for constraint error" This reverts commit 7d310514 * Check for sqlite3 constraint error * Add documentation to CreateAccount * Move ErrUserExists to accounts package * Revert "Move ErrUserExists to accounts package" Import Cycle.. This reverts commit be3d4cda Co-authored-by: Kegsay <kegan@matrix.org>
This commit is contained in:
parent
cfc137652e
commit
895c8f03c0
@ -16,6 +16,7 @@ package appservice
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
"github.com/matrix-org/dendrite/appservice/workers"
|
"github.com/matrix-org/dendrite/appservice/workers"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
|
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
||||||
|
"github.com/matrix-org/dendrite/internal"
|
||||||
"github.com/matrix-org/dendrite/internal/basecomponent"
|
"github.com/matrix-org/dendrite/internal/basecomponent"
|
||||||
"github.com/matrix-org/dendrite/internal/config"
|
"github.com/matrix-org/dendrite/internal/config"
|
||||||
"github.com/matrix-org/dendrite/internal/transactions"
|
"github.com/matrix-org/dendrite/internal/transactions"
|
||||||
@ -117,13 +119,13 @@ func generateAppServiceAccount(
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
// Create an account for the application service
|
// Create an account for the application service
|
||||||
acc, err := accountsDB.CreateAccount(ctx, as.SenderLocalpart, "", as.ID)
|
_, err := accountsDB.CreateAccount(ctx, as.SenderLocalpart, "", as.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
if errors.Is(err, internal.ErrUserExists) { // This account already exists
|
||||||
} else if acc == nil {
|
|
||||||
// This account already exists
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Create a dummy device with a dummy token for the application service
|
// Create a dummy device with a dummy token for the application service
|
||||||
_, err = deviceDB.CreateDevice(ctx, as.SenderLocalpart, nil, as.ASToken, &as.SenderLocalpart)
|
_, err = deviceDB.CreateDevice(ctx, as.SenderLocalpart, nil, as.ASToken, &as.SenderLocalpart)
|
||||||
|
@ -29,6 +29,9 @@ type Database interface {
|
|||||||
GetProfileByLocalpart(ctx context.Context, localpart string) (*authtypes.Profile, error)
|
GetProfileByLocalpart(ctx context.Context, localpart string) (*authtypes.Profile, error)
|
||||||
SetAvatarURL(ctx context.Context, localpart string, avatarURL string) error
|
SetAvatarURL(ctx context.Context, localpart string, avatarURL string) error
|
||||||
SetDisplayName(ctx context.Context, localpart string, displayName string) error
|
SetDisplayName(ctx context.Context, localpart string, displayName string) error
|
||||||
|
// CreateAccount makes a new account with the given login name and password, and creates an empty profile
|
||||||
|
// for this account. If no password is supplied, the account will be a passwordless account. If the
|
||||||
|
// account already exists, it will return nil, ErrUserExists.
|
||||||
CreateAccount(ctx context.Context, localpart, plaintextPassword, appserviceID string) (*authtypes.Account, error)
|
CreateAccount(ctx context.Context, localpart, plaintextPassword, appserviceID string) (*authtypes.Account, error)
|
||||||
CreateGuestAccount(ctx context.Context) (*authtypes.Account, error)
|
CreateGuestAccount(ctx context.Context) (*authtypes.Account, error)
|
||||||
UpdateMemberships(ctx context.Context, eventsToAdd []gomatrixserverlib.Event, idsToRemove []string) error
|
UpdateMemberships(ctx context.Context, eventsToAdd []gomatrixserverlib.Event, idsToRemove []string) error
|
||||||
|
@ -138,7 +138,7 @@ func (d *Database) CreateGuestAccount(ctx context.Context) (acc *authtypes.Accou
|
|||||||
|
|
||||||
// CreateAccount makes a new account with the given login name and password, and creates an empty profile
|
// CreateAccount makes a new account with the given login name and password, and creates an empty profile
|
||||||
// for this account. If no password is supplied, the account will be a passwordless account. If the
|
// for this account. If no password is supplied, the account will be a passwordless account. If the
|
||||||
// account already exists, it will return nil, nil.
|
// account already exists, it will return nil, ErrUserExists.
|
||||||
func (d *Database) CreateAccount(
|
func (d *Database) CreateAccount(
|
||||||
ctx context.Context, localpart, plaintextPassword, appserviceID string,
|
ctx context.Context, localpart, plaintextPassword, appserviceID string,
|
||||||
) (acc *authtypes.Account, err error) {
|
) (acc *authtypes.Account, err error) {
|
||||||
@ -164,7 +164,7 @@ func (d *Database) createAccount(
|
|||||||
}
|
}
|
||||||
if err := d.profiles.insertProfile(ctx, txn, localpart); err != nil {
|
if err := d.profiles.insertProfile(ctx, txn, localpart); err != nil {
|
||||||
if internal.IsUniqueConstraintViolationErr(err) {
|
if internal.IsUniqueConstraintViolationErr(err) {
|
||||||
return nil, nil
|
return nil, internal.ErrUserExists
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ import (
|
|||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
// Import the postgres database driver.
|
// Import the sqlite3 database driver.
|
||||||
_ "github.com/mattn/go-sqlite3"
|
"github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Database represents an account database
|
// Database represents an account database
|
||||||
@ -148,7 +148,7 @@ func (d *Database) CreateGuestAccount(ctx context.Context) (acc *authtypes.Accou
|
|||||||
|
|
||||||
// CreateAccount makes a new account with the given login name and password, and creates an empty profile
|
// CreateAccount makes a new account with the given login name and password, and creates an empty profile
|
||||||
// for this account. If no password is supplied, the account will be a passwordless account. If the
|
// for this account. If no password is supplied, the account will be a passwordless account. If the
|
||||||
// account already exists, it will return nil, nil.
|
// account already exists, it will return nil, ErrUserExists.
|
||||||
func (d *Database) CreateAccount(
|
func (d *Database) CreateAccount(
|
||||||
ctx context.Context, localpart, plaintextPassword, appserviceID string,
|
ctx context.Context, localpart, plaintextPassword, appserviceID string,
|
||||||
) (acc *authtypes.Account, err error) {
|
) (acc *authtypes.Account, err error) {
|
||||||
@ -172,8 +172,8 @@ func (d *Database) createAccount(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := d.profiles.insertProfile(ctx, txn, localpart); err != nil {
|
if err := d.profiles.insertProfile(ctx, txn, localpart); err != nil {
|
||||||
if internal.IsUniqueConstraintViolationErr(err) {
|
if errors.Is(err, sqlite3.ErrConstraint) {
|
||||||
return nil, nil
|
return nil, internal.ErrUserExists
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -830,16 +830,17 @@ func completeRegistration(
|
|||||||
|
|
||||||
acc, err := accountDB.CreateAccount(ctx, username, password, appserviceID)
|
acc, err := accountDB.CreateAccount(ctx, username, password, appserviceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.JSONResponse{
|
if errors.Is(err, internal.ErrUserExists) { // user already exists
|
||||||
Code: http.StatusInternalServerError,
|
|
||||||
JSON: jsonerror.Unknown("failed to create account: " + err.Error()),
|
|
||||||
}
|
|
||||||
} else if acc == nil {
|
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
JSON: jsonerror.UserInUse("Desired user ID is already taken."),
|
JSON: jsonerror.UserInUse("Desired user ID is already taken."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
JSON: jsonerror.Unknown("failed to create account: " + err.Error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Increment prometheus counter for created users
|
// Increment prometheus counter for created users
|
||||||
amtRegUsers.Inc()
|
amtRegUsers.Inc()
|
||||||
|
@ -69,13 +69,10 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
account, err := accountDB.CreateAccount(context.Background(), *username, *password, "")
|
_, err = accountDB.CreateAccount(context.Background(), *username, *password, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
} else if account == nil {
|
|
||||||
fmt.Println("Username already exists")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceDB, err := devices.NewDatabase(*database, nil, serverName)
|
deviceDB, err := devices.NewDatabase(*database, nil, serverName)
|
||||||
|
@ -26,6 +26,9 @@ import (
|
|||||||
"go.uber.org/atomic"
|
"go.uber.org/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrUserExists is returned if a username already exists in the database.
|
||||||
|
var ErrUserExists = errors.New("Username already exists")
|
||||||
|
|
||||||
// A Transaction is something that can be committed or rolledback.
|
// A Transaction is something that can be committed or rolledback.
|
||||||
type Transaction interface {
|
type Transaction interface {
|
||||||
// Commit the transaction
|
// Commit the transaction
|
||||||
|
Loading…
Reference in New Issue
Block a user