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:
$ref: '#/components/schemas/input-error'
description: Either the username or the email address is already used.
type: object
- 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
description: The server cannot deliver due to an internal error.
package user
import (
......@@ -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",
raven.CaptureError(unameErr, nil)
ctx.AbortWithError(http.StatusInternalServerError, unameErr)
} else {
ctx.AbortWithStatusJSON(http.StatusConflict, gin.H{
"field": "username",
eventID := raven.CaptureError(err, nil)
ctx.String(http.StatusInternalServerError, "Failed inserting user. "+eventID)
......@@ -24,7 +24,7 @@ import (
_ ""
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
// 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