Receiving different exceptions when trying to update the "additionalData" map from "PasswordProfile" from "User" resource
Expected behavior
Updating the map "additionalData" from "PasswordProfile" from "User" resource by adding some entries. I'm trying to add a field called "password-reset-verify-token" of type String.
I'm using:
What could cause my issues? And is there any documentation regarding the naming conventions regarding the namings and formats of the data from "additionalData" map?
Thank you!
Actual behavior
1. First behaviour
- trying to add the field as key-value (
String-String) which results in: com.microsoft.graph.models.odataerrors.ODataError: Expected property 'password-reset-verify-token' is not present on resource of type 'PasswordProfile'
Code
private static void setResetPasswordVerifyTokenOnUser3(
GraphServiceClient graphServiceClient, String userEmail, String verifyToken) {
User userResource = getUserFromUserEmail(graphServiceClient, userEmail);
User userResourceWithUpdates = new User();
PasswordProfile passwordProfile = new PasswordProfile();
Map<String, Object> additionalData = new HashMap<>();
additionalData.put("password-reset-verify-token", verifyToken);
passwordProfile.setAdditionalData(additionalData);
userResourceWithUpdates.setPasswordProfile(passwordProfile);
try {
graphServiceClient.users().byUserId(userResource.getId()).patch(userResourceWithUpdates);
} catch (Exception e) {
// throw exception
}
}
Outcome
com.microsoft.graph.models.odataerrors.ODataError: Expected property 'password-reset-verify-token' is not present on resource of type 'PasswordProfile'
at com.microsoft.graph.models.odataerrors.ODataError.createFromDiscriminatorValue(ODataError.java:36)
at com.microsoft.kiota.serialization.JsonParseNode.getObjectValue(JsonParseNode.java:212)
at com.microsoft.kiota.http.OkHttpRequestAdapter.lambda$throwIfFailedResponse$0(OkHttpRequestAdapter.java:674)
at com.microsoft.kiota.ApiExceptionBuilder.<init>(ApiExceptionBuilder.java:26)
at com.microsoft.kiota.http.OkHttpRequestAdapter.throwIfFailedResponse(OkHttpRequestAdapter.java:673)
at com.microsoft.kiota.http.OkHttpRequestAdapter.send(OkHttpRequestAdapter.java:281)
at com.microsoft.graph.users.item.UserItemRequestBuilder.patch(UserItemRequestBuilder.java:779)
at com.microsoft.graph.users.item.UserItemRequestBuilder.patch(UserItemRequestBuilder.java:763)
2. Second behaviour
- trying to add the field as key-value (
String-Object) which results in: java.lang.IllegalStateException: Dangling name: password-reset-verify-token
Code
private static void setResetPasswordVerifyTokenOnUser3(
GraphServiceClient graphServiceClient, String userEmail, String verifyToken) {
User userResource = getUserFromUserEmail(graphServiceClient, userEmail);
User userResourceWithUpdates = new User();
PasswordProfile passwordProfile = new PasswordProfile();
Map<String, Object> additionalData = new HashMap<>();
record PasswordAdditionalData(@JsonProperty("password_reset_verify_token") String passwordResetVerifyToken) {}
PasswordAdditionalData passwordAdditionalData = new PasswordAdditionalData(verifyToken);
additionalData.put("password-reset-verify-token", passwordAdditionalData);
passwordProfile.setAdditionalData(additionalData);
userResourceWithUpdates.setPasswordProfile(passwordProfile);
try {
graphServiceClient.users().byUserId(userResource.getId()).patch(userResourceWithUpdates);
} catch (Exception e) {
// throw exception
}
}
Outcome
java.lang.IllegalStateException: Dangling name: password-reset-verify-token
at com.google.gson.stream.JsonWriter.close(JsonWriter.java:346)
at com.google.gson.stream.JsonWriter.endObject(JsonWriter.java:321)
at com.microsoft.kiota.serialization.JsonSerializationWriter.writeObjectValue(JsonSerializationWriter.java:316)
at com.microsoft.graph.models.User.serialize(User.java:1279)
at com.microsoft.kiota.serialization.JsonSerializationWriter.writeObjectValue(JsonSerializationWriter.java:301)
at com.microsoft.kiota.RequestInformation.setContentFromParsable(RequestInformation.java:337)
at com.microsoft.graph.users.item.UserItemRequestBuilder.toPatchRequestInformation(UserItemRequestBuilder.java:854)
at com.microsoft.graph.users.item.UserItemRequestBuilder.patch(UserItemRequestBuilder.java:776)
at com.microsoft.graph.users.item.UserItemRequestBuilder.patch(UserItemRequestBuilder.java:763)
Steps to reproduce the behavior
See the code snippets attached above
Thanks for raising this @GBadila
I believe the first example is appropriate in adding a property, however the API is failing as the type does not accept/support the new property name. Any chance you can confirm if what you are trying to achieve by sharing a json representation of the desired object?
According to the API docs, the only supported properties by the api are documented at https://learn.microsoft.com/en-us/graph/api/resources/passwordprofile?view=graph-rest-1.0
Hi @andrueastman!
As per the documentation you linked PasswordProfile should have only 3 fields to set up:
- forceChangePasswordNextSignIn
- forceChangePasswordNextSignInWithMfa
- password
But based on the latest version of the Java SDK for Microsoft Graph it looks like there are 6 setter methods.
- snippet from PasswordProfile (https://github.com/microsoftgraph/msgraph-sdk-java/blob/main/src/main/java/com/microsoft/graph/generated/models/PasswordProfile.java#L115-L157)
public void setAdditionalData(@Nullable final Map<String, Object> value) {
this.backingStore.set("additionalData", value);
}
public void setBackingStore(@Nonnull final BackingStore value) {
Objects.requireNonNull(value);
this.backingStore = value;
}
public void setForceChangePasswordNextSignIn(@Nullable final Boolean value) {
this.backingStore.set("forceChangePasswordNextSignIn", value);
}
public void setForceChangePasswordNextSignInWithMfa(@Nullable final Boolean value) {
this.backingStore.set("forceChangePasswordNextSignInWithMfa", value);
}
public void setOdataType(@Nullable final String value) {
this.backingStore.set("odataType", value);
}
public void setPassword(@Nullable final String value) {
this.backingStore.set("password", value);
}
Which made me think that I could use that setAdditionalData method for my own use-case.
I'm trying to have a flow where:
- When reset password is requested by the client the server generates a
verify token(and saves it in thatadditional datamap). - The verify token is sent to the user and the user provides the verify token to the client.
- The client sends the verify token to the server.
- The server retrieves the verify token from
additional datamap and compares the 2 tokens. - If the tokens are the same the password is updated.
So basically, I'm trying to add an entry String:String (key:value) to the additional data map, which errors out as mentioned in my issue.
Unfortunately, in this scenario I don't believe it is possible to add extra properties to the PasswordProfile type and send them to the Graph API.
The AdditionalData property exists in all models in the SDK to enable extensibility as you would have liked to use it as well as holding extra properties returned in the API that are not described.
The AdditionalData property exists in all models in the SDK to enable extensibility as you would have liked to use it as well as holding extra properties returned in the API that are not described.
Then if it's not meant to be used by adding additional properties by the user why let the setter method under the public access modifier? Or if it has to be public why not attached a comment to let people know is not meant to be used by the users? It's a bit confusing as it is at the moment.
Closing since API does not support adding additional properties & the additionalData property was not designed for this purpose.