thingsboard / rule-node-examples

Examples of custom Rule Nodes for ThingsBoard contribution guide
Apache License 2.0
14 stars 52 forks source link

unable to import org.thingsboard.server.service.security.model.SecurityUser #14

Closed skewty closed 2 years ago

skewty commented 2 years ago

Here is what I see in IntelliJ: image

As an alternate path forward, I tried adding this into pom.xml and loading Maven changes but it errors out because it isn't valid either

<dependency>
    <groupId>org.thingsboard.service</groupId>
    <artifactId>security</artifactId>
    <scope>provided</scope>
    <version>${thingsboard.version}</version>
</dependency>

I looked around at https://repo.thingsboard.io/artifactory/libs-release-public/org/thingsboard/ to see if I could find something that might work for me but never figured it out myself.


I am trying to use entityGroupService.findGroupEntities() which requires MergedUserPermissions as a parameter. org.thingsboard.server.controller.EntityGroupController.getEntities() seems to be able to get them from a SecurityUser but I can't seem to get that far. My proof-of-concept code so far is:

    @Override
    public void onMsg(TbContext ctx, TbMsg msg) {
        var tenantId = ctx.getTenantId();
        var customerId = msg.getCustomerId();
        var userId = new UserId(UUID.fromString(msg.getMetaData().getValue("userId")));
        var permissions = new SecurityUser(userId).getUserPermissions();
        var entityGroupId = new EntityGroupId(UUID.fromString("Cleaner-Inspectors-User-Group")); // todo real UUID
        var pageLink = new PageLink(100);
        var entityGroupService = ctx.getPeContext().getEntityGroupService();
        var pageData = entityGroupService.findGroupEntities(tenantId, customerId, permissions, entityGroupId, pageLink);

Is there perhaps an alternate / easier way to generate a MergedUserPermissions since unlike the web API the rule engine should always have permission to do the query?

Is there an easy way to get MergedUserPermissions for my tenantId "Tenant Admin" for example?

smatvienko-tb commented 2 years ago

RuleEngine is not running under a particular user. And user-related stuff is hard to find an example. The user never logs in to the rule engine, and the rule engine may run as a separate microservice. Maybe some other methods will be applicable for you like

findAllEntityGroups
findEntityGroupByTypeAndName
findEntityGroupsForEntity

etc

skewty commented 2 years ago

Here is my use case / problem I am trying to solve:

I have some tri-state asset attributes controlled by a custom widget we created. It is basically just a <mat-slider> that allows only values: 0, 1, 2.

Only users belonging to "UserGroup A" can change the value from 0 <-> 1. Only users belonging to "UserGroup B" can change the value from 1 <-> 2. Only users belonging to "UserGroup C" can change the value from 2 <-> 0. I need other changes "blocked" by the RuleChain.

Workflow attribute changes have userId in metadata so I get it from there. I need to figure out if userId belongs to a certain user group.

UserGroup A, UserGroup B and UserGroup C will be part of my TbNodeConfiguration.

Isn't findGroupEntities() the correct call to see if userId is part of a known UserGroup?

Unless my understanding is wrong, the other calls give me the Entity Groups (User Groups) themselves, not the Entities (Users) that are within them.

AlexDoanTB commented 2 years ago

Isn't findGroupEntities() the correct call to see if userId is part of a known UserGroup?

@skewty the getEntities API uses findGroupEntities() to return a list of entities in the targeted group.

smatvienko-tb commented 2 years ago

Hi!

SecurityUser is located on application root component. And I see no options for how to import applications as a dependency of the rule engine.

Please avoid fetching a list of entities when you need a single answer. This adds more complexity and increases the load on the database.

I believe there is a solution available using isEntityInGroup method.

Your requirement "User belongs to UserGroup" has an implementation like a:

        EntityGroupService entityGroupService = ctx.getPeContext().getEntityGroupService();
        EntityId entityId = UserId.fromString("02d63580-897b-4347-822b-b113b8adc43b");
        EntityGroupId entityGroupId = EntityGroupId.fromString("05aa65a0-511c-40d5-87db-44828b05b24c");
        boolean isEntityInGroup = entityGroupService.isEntityInGroup(ctx.getTenantId(), entityId, entityGroupId);

The code example is here: https://github.com/smatvienko-tb/rule-node-examples/pull/1/commits/c4a8d7b07642369c9cc6dec0ab6f12779dff41e8

If you have any concerns about implementing some use cases, please hit the general ThingsBoard issue. Or create a request as a PE user if you can do that. This tiny repo is about how to do the first steps into custom rule nodes development! The general repo issues-answers might be useful for the wider community as well.

Have a great day!