FusionAuth / fusionauth-issues

FusionAuth issue submission project
https://fusionauth.io
90 stars 12 forks source link

Bulk user import handles Elasticsearch errors differently with multiple users vs one user #2687

Open bhalsey opened 6 months ago

bhalsey commented 6 months ago

Bulk user import handles Elasticsearch errors differently with multiple users vs one user

Description

When a bulk user import has Elasticsearch errors, there is no indication when there is more than one user (typical use for bulk). If there is only one user, a misleading error message is returned.

Observed versions

1.49.1

Affects versions

All

Steps to reproduce

We'll use different custom data field types to trigger Elasticsearch errors. There's an existing issue acknowledging problems arising from this, https://github.com/FusionAuth/fusionauth-issues/issues/1149.

First, we create two users with a numeric data.attr1 field.

curl -i -H "Authentication: $APIKEY" -H "X-FusionAuth-TenantId: $TENANT" -H "Content-type: application/json" http://localhost:9011/api/user/import -d '{                                                                                                                                                                        
  "users": [
    {
      "email": "username1@test.com",
      "password": "password",
      "username": "username1",
      "data": {
        "attr1": 1111
      }
    },
    {
      "email": "username2@test.com",
      "password": "password",
      "username": "username2",
      "data": {
        "attr1": 2222
      }
    }
  ],
  "validateDbConstraints": true
}'

HTTP/1.1 200

Then we create two users with a string data.attr1 field.

curl -i -H "Authentication: $APIKEY" -H "X-FusionAuth-TenantId: $TENANT" -H "Content-type: application/json" http://localhost:9011/api/user/import -d '{                                                                                                                                                                        
  "users": [
    {
      "email": "username3@test.com",
      "password": "password",
      "username": "username3",
      "data": {
        "attr1": "value3"
      }
    },
    {
      "email": "username4@test.com",
      "password": "password",
      "username": "username4",
      "data": {
        "attr1": "value4"
      }
    }
  ],
  "validateDbConstraints": true
}'
HTTP/1.1 200

Notice that when we create one user with with a string data.attr1 field, we get a misleading error back:

curl -i -H "Authentication: $APIKEY" -H "X-FusionAuth-TenantId: $TENANT" -H "Content-type: application/json" http://localhost:9011/api/user/import -d '{                                                                                                                                                                        
  "users": [
    {
      "email": "username5@test.com",
      "password": "password",
      "username": "username5",
      "data": {
        "attr1": "value5"
      }
    }
  ],
  "validateDbConstraints": true
}'
HTTP/1.1 400

{"fieldErrors":{},"generalErrors":[{"code":"[ImportRequestFailed]","message":"An error occurred during the import request. This is most likely due to a unique key constraint which would indicate one or more of the users in the import request already exist in FusionAuth. Re-attempt the request with additional validation by using the [validateDbConstraints] property. If you have already enabled the additional validation and you still receive this error, please open a bug report."}]}

Furthermore, if we create a similar single user with the non bulk endpoint, we don't get an error back.

curl -i -H "Authentication: $APIKEY" -H "X-FusionAuth-TenantId: $TENANT" -H "Content-type: application/json" http://localhost:9011/api/user -d '{"user":                                                                                                                                                                            {
      "email": "username6@test.com",
      "password": "password",
      "username": "username6",
      "data": {
        "attr1": "value6"
      }
    }
}'
HTTP/1.1 200

{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjRmMDZkN2Y4YiJ9.eyJleHAiOjE3MTA4NzAwNzQsImlhdCI6MTcxMDg2NjQ3NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiI4ZDFiMjRmYy1hNjg0LTQ1MGYtOWM2ZC01MDFiOTc2M2Y4NDAiLCJqdGkiOiJhOTNlMjFkYi1jM2RhLTQxMzItOGY0Mi1lMjI5MGVhYjE3MWUiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJVU0VSX0NSRUFURSIsImVtYWlsIjoidXNlcm5hbWU2QHRlc3QuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJ1c2VybmFtZTYiLCJhdXRoX3RpbWUiOjE3MTA4NjY0NzQsInRpZCI6IjMwNjYzMTMyLTY0NjQtNjY2NS0zMDMyLTMyNjQ2NjYxMzkzNCJ9.-jw183kvMviDrXv2j5wap9igK_HKUsC7L9_L_5eOlKY","tokenExpirationInstant":1710870074540,"user":{"active":true,"connectorId":"e3306678-a53a-4964-9040-1c96f36dda72","data":{"attr1":"value6"},"email":"username6@test.com","id":"8d1b24fc-a684-450f-9c6d-501b9763f840","insertInstant":1710866474495,"lastLoginInstant":1710866474495,"lastUpdateInstant":1710866474495,"memberships":[],"passwordChangeRequired":false,"passwordLastUpdateInstant":1710866474531,"preferredLanguages":[],"registrations":[],"tenantId":"30663132-6464-6665-3032-326466613934","twoFactor":{"methods":[],"recoveryCodes":[]},"uniqueUsername":"username6","username":"username6","usernameStatus":"ACTIVE","verified":false}}

We can verify that only the first two users are actually indexed in Elasticsearch

curl -s -H "Authentication: $APIKEY" -H "X-FusionAuth-TenantId: $TENANT" -H "Content-type: application/json" 'http://localhost:9011/api/user/search?queryString=username' | jq '.users[].username'                                                                                                                              

"username1"
"username2"

Expected behavior

I expect the bulk user import endpoint to handle Elasticsearch errors consistently, whether importing one user or multiple users . An Elasticsearch specific error message would be helpful. It is also surprising that the user create (non-bulk) endpoint does not report Elasticsearch errors.