FusionAuth / fusionauth-issues

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

[Bug]: API requests resulting in "ValidationException: null" #2677

Closed ntaisee closed 6 months ago

ntaisee commented 6 months ago

What happened?

I am trying to send an API request for the "Create a User and Registration (combined)" endpoint. I have tried using both the .NET SDK as well as creating the request myself. Both result in a 500 status code and the following error:

2024-03-06 14:52:56 2024-03-06 07:52:56.573 PM ERROR org.primeframework.mvc.PrimeMVCRequestHandler - Error encountered
2024-03-06 14:52:56 org.primeframework.mvc.validation.ValidationException: null
2024-03-06 14:52:56     at org.primeframework.mvc.validation.DefaultValidationProcessor.validate(DefaultValidationProcessor.java:91)
2024-03-06 14:52:56     at org.primeframework.mvc.validation.DefaultValidationWorkflow.perform(DefaultValidationWorkflow.java:44)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.security.DefaultSecurityWorkflow.perform(DefaultSecurityWorkflow.java:79)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.parameter.DefaultPostParameterWorkflow.perform(DefaultPostParameterWorkflow.java:49)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.content.DefaultContentWorkflow.perform(DefaultContentWorkflow.java:74)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.parameter.DefaultParameterWorkflow.perform(DefaultParameterWorkflow.java:58)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.parameter.DefaultURIParameterWorkflow.perform(DefaultURIParameterWorkflow.java:92)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.scope.DefaultScopeRetrievalWorkflow.perform(DefaultScopeRetrievalWorkflow.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.action.DefaultActionMappingWorkflow.perform(DefaultActionMappingWorkflow.java:119)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.security.DefaultSavedRequestWorkflow.perform(DefaultSavedRequestWorkflow.java:65)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.cors.CORSFilter.doFilter(CORSFilter.java:171)
2024-03-06 14:52:56     at org.primeframework.mvc.cors.CORSRequestWorkflow.perform(CORSRequestWorkflow.java:63)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.SubWorkflowChain.continueWorkflow(SubWorkflowChain.java:50)
2024-03-06 14:52:56     at org.primeframework.mvc.workflow.DefaultMVCWorkflow.perform(DefaultMVCWorkflow.java:108)
2024-03-06 14:52:56     at org.primeframework.mvc.PrimeMVCRequestHandler.handle(PrimeMVCRequestHandler.java:73)
2024-03-06 14:52:56     at io.fusionauth.http.server.HTTPWorker.run(HTTPWorker.java:50)
2024-03-06 14:52:56     at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
2024-03-06 14:52:56     at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
2024-03-06 14:52:56     at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
2024-03-06 14:52:56     at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
2024-03-06 14:52:56     at java.base/java.lang.Thread.run(Thread.java:833)

Snippet for trying through the SDK:

var registerReq = new RegistrationRequest();

// Add the new user details
registerReq.user = new User();
registerReq.user.username = membershipUser.UserName;
registerReq.user.email = membershipUser.Email;

// Add the app details
registerReq.registration = new UserRegistration();
registerReq.registration.applicationId = new Guid(applicationId);

// Send the request
var client = new FusionAuthSyncClient(ConfigurationManager.AppSettings["FusionAuth:APIKey"], ConfigurationManager.AppSettings["FusionAuth:URL"], ConfigurationManager.AppSettings["FusionAuth:TenantId"]);
var response = client.Register(new Guid(membershipUser.ProviderUserKey.ToString()), registerReq);

Snippet for trying through HTTPClient:

var requestData = new Dictionary<string, object>
{
    {
        "registration", new Dictionary<string, object>
        {
            { "application", applicationId }
        }
    },
    {
        "user", new Dictionary<string, object>
        {
            { "username", membershipUser.UserName },
            { "email", membershipUser.Email }
        }
    }
};
var requestJSON = JsonConvert.SerializeObject(requestData);
var requestContent = new StringContent(requestJSON, Encoding.UTF8, "application/json");

HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", ConfigurationManager.AppSettings["FusionAuth:APIKey"]);
client.DefaultRequestHeaders.Add("X-FusionAuth-TenantId", ConfigurationManager.AppSettings["FusionAuth:TenantId"]);

var response = await client.PostAsync(ConfigurationManager.AppSettings["FusionAuth:URL"] + "/api/user/registration/" + membershipUser.ProviderUserKey.ToString(), requestContent);

I have also tried to just create a user, but get the same result. Code snippet:

var newUser = new UserRequest()
{
   user = new User
   {
       username = membershipUser.UserName,
       email = membershipUser.Email
   }
};

var client = new FusionAuthSyncClient(ConfigurationManager.AppSettings["FusionAuth:APIKey"], ConfigurationManager.AppSettings["FusionAuth:URL"], ConfigurationManager.AppSettings["FusionAuth:TenantId"]);
var response = client.CreateUser(null, newUser);

I have verified I can use the SDK to get an existing FusionAuth user.

Version

1.48.3

Affects Versions

No response

ntaisee commented 6 months ago

I feel as though I'm going crazy. Didn't alter much, but now the requests are working. I added the sendSetPasswordEmail parameter, which I swore I had added before and had the same issue.

I guess FusionAuth was failing validation due to the missing password parameter, but kicking back that ugly, unhelpful error. Funny thing is, I sent the request without sendSetPasswordEmail using Postman, and got a proper error response there.

I suppose this should be closed?

Updated SDK snippet for future reference:

var registerReq = new RegistrationRequest();
registerReq.sendSetPasswordEmail = true;

// Add the new user details
registerReq.user = new User();
registerReq.user.username = membershipUser.UserName;
registerReq.user.email = membershipUser.Email;

// Add the app details
registerReq.registration = new UserRegistration();
registerReq.registration.applicationId = new Guid(applicationId);

// Send the request
var client = new FusionAuthSyncClient(ConfigurationManager.AppSettings["FusionAuth:APIKey"], ConfigurationManager.AppSettings["FusionAuth:URL"], ConfigurationManager.AppSettings["FusionAuth:TenantId"]);
var response = client.Register(new Guid(membershipUser.ProviderUserKey.ToString()), registerReq);

Updated POST request snippet for future reference:

var requestData = new Dictionary<string, object>
{
    { "sendSetPasswordEmail", true },
    {
        "registration", new Dictionary<string, object>
        {
            { "applicationId", applicationId }
        }
    },
    {
        "user", new Dictionary<string, object>
        {
            { "username", membershipUser.UserName },
            { "email", membershipUser.Email }
        }
    }
};
var requestJSON = JsonConvert.SerializeObject(requestData);
var requestContent = new StringContent(requestJSON, Encoding.UTF8, "application/json");

HttpClient client = new HttpClient();
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["FusionAuth:URL"]);
client.DefaultRequestHeaders.Add("Authorization", ConfigurationManager.AppSettings["FusionAuth:APIKey"]);
client.DefaultRequestHeaders.Add("X-FusionAuth-TenantId", ConfigurationManager.AppSettings["FusionAuth:TenantId"]);

var response = await client.PostAsync("/api/user/registration/" + membershipUser.ProviderUserKey.ToString(), requestContent);