Commit 13957845 authored by Julien Schröter's avatar Julien Schröter Committed by Julien Schröter

Provide HTTP status 409 and conflicting field on /register endpoint

Email address and username must always be unique. Register will answer
with HTTP status code 409 Conflict when a user tries to use an existing
username or tries to reuse an email address to create a new account.

The endpoint will also return an json object with a field "field"
providing information which attribute failed.

When the username and the email address are both reused, the field will
have the value "username".
parent 28790d85
Pipeline #1966 failed with stages
in 45 seconds
......@@ -241,6 +241,18 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/input-error'
'409':
description: Either the username or the email address is already used.
content:
application/json:
schema:
type: object
required:
- field
properties:
field:
description: The field which failed, eiter 'username' or 'email'. If both, the email address and the username, are already used, the field will be 'username'.
type: string
'500':
description: The server cannot deliver due to an internal error.
content:
......
package user
import (
"database/sql"
"fmt"
"net/http"
"net/mail"
......@@ -90,6 +91,26 @@ func RegisterUser(repository UserQuery, tokenFactory otp.TokenFactory, verifyEma
id, err := repository.Insert(&user, signUpForm.Password)
if err != nil {
if err == ErrUniqueKey {
if _, unameErr := repository.SelectByUsername(user.Username); unameErr != nil {
if unameErr == sql.ErrNoRows {
ctx.AbortWithStatusJSON(http.StatusConflict, gin.H{
"field": "email",
})
return
}
raven.CaptureError(unameErr, nil)
ctx.AbortWithError(http.StatusInternalServerError, unameErr)
return
} else {
ctx.AbortWithStatusJSON(http.StatusConflict, gin.H{
"field": "username",
})
return
}
}
eventID := raven.CaptureError(err, nil)
ctx.String(http.StatusInternalServerError, "Failed inserting user. "+eventID)
return
......
......@@ -24,7 +24,7 @@ import (
"gitlab.akamu.de/akamu/game-server-go/dbhandler"
"gitlab.akamu.de/akamu/game-server-go/schemas"
_ "github.com/go-sql-driver/mysql"
"github.com/go-sql-driver/mysql"
)
type UserQuery interface {
......@@ -54,6 +54,8 @@ var ErrUnverified = errors.New("user is not verfied")
// ErrUpdateForbidden is returned when a user tries to set an avatar or title which is not unlocked.
var ErrUpdateForbidden = errors.New("tried to set locked avatar or title")
var ErrUniqueKey = errors.New("tried to reuse value with an unique attribute")
/*
* adds the new user to the database and saves the respective id value to the signInResponse.
* FullUserSchema specific attributes are taken from the signUpForm while non user
......@@ -97,6 +99,12 @@ func (MySQLUserQuery) Insert(user *schemas.FullUserSchema, password string) (id
if err != nil {
//if an error occured Rollback the transaction
tx.Rollback()
// There may already be an user with that username or email address
if mErr, ok := err.(*mysql.MySQLError); ok && mErr.Number == 1062 {
return 0, ErrUniqueKey
}
return 0, fmt.Errorf("Failed executing insert query statement. " + err.Error())
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment