简体   繁体   中英

Create Gentics Mesh User Profile node during JWT user mapping - causes failure

I'm working on an authentication plugin that uses JWT parsing to get details and update the user in Mesh.
I'd like to also create a new node and attach it to the User in Mesh, using the user.setNodeReference() // Is this how I associate a User to a node?

The problem is when I return the mapping result, if I create the user profile node, I see the mapToken() method invoked again with the same token as before, like it's looping. I've found this is due to the 'retry' capabilities in the router

If I dont attach a node to the user.nodeReference() then it proceeds as expected.

Thoughts?

    @Override
    public MappingResult mapToken(HttpServerRequest req, String uuid, JsonObject token) {
        MappingResult result = new MappingResult();

        if (uuid == null) {
            log.info("First time login of the user");
        } else {
            log.info("Already synced user is logging in.");
        }

        log.info("Mapping user in plugin");
        printToken(token);
        String username = extractUsername(token).get();
        UserUpdateRequest user = new UserUpdateRequest();
        user.setUsername(username);
        user.setEmailAddress(username);
        user.setFirstname(token.getString("firstname", "firstname"));
        user.setLastname(token.getString("lastname", "lastname"));

        // TODO: Stop the infinite loop
        if (uuid == null) {
            log.info("Creating profile node");
            user.setNodeReference(createProfileNode(username, token));
        } else {
            log.info("Updating profile node");
            //updateProfileNode(uuid, token);
        }

        result.setUser(user);

...
}

    private ExpandableNode createProfileNode(String username, JsonObject token) {

        NodeCreateRequest nodeCreateRequest = new NodeCreateRequest()
                .setLanguage("en")
                .setSchemaName(getConfig().getProfileSchema())
                .setParentNodeUuid(getConfig().getProfileParentUuid());
        FieldMap fields = nodeCreateRequest.getFields();
        fields.putString("name", username);
        fillProfileFieldMappedValues(fields, token);
        nodeCreateRequest.setFields(fields);
        return this.adminClient.createNode(getConfig().getProjectName(), nodeCreateRequest).blockingGet();
    }

Update

I checked the jti & iat - the token contains both.
I thought maybe if I subscribe to the USER_CREATED event, I could add a profile node after the user is created.
But I don't see this ever executed. I may be incorrectly subscribing to the local event bus.

getRxVertx().eventBus().localConsumer(MeshEvent.USER_CREATED.getAddress()).handler((message) -> {
  try {
    String uuid = JsonUtil.getMapper().readTree(message.body().toString()).get("uuid").asText();
                adminClient().findUserByUuid(uuid).toSingle().doAfterSuccess(u -> {              
      u.setNodeReference(createProfileNode(u.getUuid()).getBody());                
    }).doOnError(e -> {
        log.error("Failed to create user profile node: {}", e);      
      });           
    } catch (IOException e) {
        log.error("Failed to deserialize user: {}", e);
    }
});

Also, I don't need to set the user.setNodeReference() to reproduce the error, I only need to try creating a new node in the mapToken method. It will retry creating the user 10x then error out with an http 500.
I'll turn up logging to see if I can get more details.

Update I've found that if I create the user first in the mapToken function, then create a node for the profile, I can add it to the user.setNodeReference() but I never see the node in the content browser [I create it at `{project}/profiles/{userProfileNode}], and I'm not able to see the node reference when I retrieve the user.

But the logs show the node was created successfully.

Does your token contain a token Id? (jti or iat). Mesh will use one of these values to determine whether the key mapping needs to be re-run for the token. The idea behind this is to avoid bogus mapping calls for tokens that have not changed. I suspect your token does not pass this check and will be passed always to the mapper plugin.

I might be able to give you more hints if I could see some logs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM