3

I'm asking this question for a colleague since he doesn't have enough reputation to post images in a question

During our normal development we found a deficit in our REST Api. We display entities in our UI like this. Whereby the buttons at the top are so called actions.

In the Image you can see buttons which act as actions and a Kendo Grid/Table component. The Entry ReportExecutionJob is selected in the table and now the actions can either be used on that selection or not.

In depth details

An action itself is generic. It doesn't know a lot of stuff or metadata and more over just performs a task on any given object. For example you can add an action called delete and it will try to delete whatever entity you gave to it.

We have a user permission system and an seperated general permission system which will tell which actions are allowed on a given entity.

Example: There can be an permission that you can perform the delete action on entity X but on the same instance the user might not have the permission to invoke the action at all.

Problem

When for example the ReportExecutionJob is selected we perform a check in the FrontEnd if the action (Pause for example) is generally allowed for the selected Entity. Afterwards the Backend holds the business logic to check if the user has the permission to invoke that action on the selected entry.

Resulting in two places handling one topic/problem.

Questions

There are some questions on how to do this the most efficient and safest way.

Would you suggest to get the informations (allowed on entity, allowed by user) as part of the entity in the response?

Should it be loaded from the Action itself ( so when something is selected, a request in the background is done which gets a result if the action is enabled or disabled on the entity and if the user is allowed)

Is there a best practice method or recommendation?

And also my colleague has the question when all this should be done. Wether on loading the page, when selecting the entry in the table or when trying to perform the action?

  • 3
    What kind of "leak" did you find, and how is it connected to the question you asked? Does the app leak information? Does it allow things that shouldn't be? Does it spend more resources than would be necessary? – Kilian Foth Jan 23 '18 at 11:02
  • I'm very sorry for the missleading sentence. It's more of a deficit than a leak. I didn't check closely enough what he wrote me. I hope you can understand the wording deficit more than leak @KilianFoth – Nico Jan 23 '18 at 11:44
  • 2
    You can have the API also send allowed actions along with each resource, in context of the user who is viewing such resource. Hence you can simply enable or disable actions based on the data you have. Strict checks on API side are obviously always required. – S.D. Jan 23 '18 at 12:32
2

There are a few ways to handle this, but generally you will ideally have the information on the client before the new drop down item is selected, for user experience reasons.

From there, it’s really up to you how you tell the front end what actions a given item is allowed, but one method I’ve seen that is pretty clean is by using HATEOAS (Hypertext As the Engine Of Application State).

In that case, each time you fetch a resource from the server, it’d include all the data, but then also include metadata in the form of links to the other supported actions. That would be an easy way to tell the client what other actions are supported for the current user, and the client could figure out what buttons to display or enable.

  • As I found out now my colleague also can't write comments, so sorry for late answers. He said that the idea is interesting but pretty much not what is possible for us. The picture you see is a Kendo Grid ( table ) and not a dropdown. His question is more over when those kind of informations should be exchanged and how. I will try editing the question in my own wording to get across what he means. – Nico Jan 23 '18 at 12:09
  • 2
    Drop-down was an example, the fact that it's a kendo grid doesn't change my answer. The point is to populate your UI, at some point you're fetching information from the server. When that happens, if you provide metadata about each data elements that includes the URLs to the related API calls possible by the user, you then have that info available to the client for updating the UI appropriately. – Paul Jan 23 '18 at 12:18
1

It seems like you have two separate problems.

  1. Does the user have permission to execute the command

A good way to attack this is to have an access token with verbose claims "canRunActionX" then both the client and server can run the same check and get the same result.

  1. Does generic entity X allow generic action Y

In this case it seems generally unlikely that the actions per entity will change much. You are never going to be able to reformat a monitor.

Or there will be clear logic which defines when the action is valid. You cant pause a video which is not playing.

I would hardcore this into the client and save myself the round trip to ask something i already know the answer to.

The HATEOS approach of telling the client what else they can do never works in my experience. The client must be programmed to understand the possible extra actions and be able to call them. So you end up with everything hard-coded either way.

  • The answer of @bbqq92 is an answer to your post. Since he didn't have enough reputation to post images. He added some further insight and questions according to your answer. – Nico Jan 25 '18 at 7:23
1
  1. Does the user have permission to execute the command

FYI: Currently we plan to solve this by a permission system in the BE which checks if user have a permission assigned if not the action (button) won't be rendered. Client will call rest and get all assigned permissions and could check what a user is able to do or what not (all permissions are transfered at client startup).

  1. Does generic entity X allow generic action

I would hardcore this into the client and save myself the round trip to ask something i already know the answer to.

This is what we currently do. A check is coded in the BE and in the FE. I also totally agree with your argumentation against HATEOS.

BE adds Meta Infos to Data

We fear that businesslogic is tranfered to the client because checks like if (entity.field === "State 10" && otherEntity.locked = false ) {....}

Our fear is that we:

  • Repeat ourselfs
  • A FE and BE developer is needed to adjust logic checks
  • Businesslogic could / would be transfered to the FE
  • Adding these metadata to our data is slow (see below)

When we add metadata to our entites like (similar to HATEOS) :

[ 
  { 
    _actions: [ xy_allowed: true ], 
    name: "ReportExecutionJob", 
    otherFields: ...
  },
.... 
]

We need to perform the check if action is allowed for every data line. This will be done in the BE before the data are send to the client. So a check if action "could" be allowed is done in every case, which will cost (waste) time.

Enabling / Disabling of an action will be done when a user selecting an entity or multiple entities in the UI only. So adding metadata is maybe not the best solution because it's not clear if a user will / can select this line so that the check is really needed.

Another problem here is, as you also already told, that the FE needs to know every possible action and code against this action name in the FE.

Action ask rest

During a discussion we get also another Idea.

After a User selects a entry / entries in the UI. All actions which on the page could make a rest request to the BE. (so all actions which are not rendered won't cause traffic)

Content of the request could be entity ID ( & Version in some cases ) in the BE all checks are done (logic is only in BE) and BE returns info if action is allowed or not.

But also here we have some points against it:

  • Could be slow because BE needs to request Database again to get the entity by ID
  • It could take a while till action get's enabled in the UI ( other solution will enable / disable the action faster because infos are already in UI )

.......................................................................

so for BE adds Meta Infos to Data there is a default (HATEOAS) which can be used.

Is there also a standart to let an action making a request to the BE to check if it's allowed or not?

Code it twice is also still in the race.

We are also searching try to find a "better" solution (best practices) to do this and open for new ideas or remarks .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.