How to do segmentation in endeca for a specific user (registered user and anonymous user) - endeca

How can we show the specific content the user based on their status i.e logged in user are not logged in user(anonymous user) and based on that we have to show the specific content that is configured in endeca work bench.and one more thing in this task is that to it has to consider another parameter that user is sending the request from which device(tablet or desktop or loptap or mobile)?
How can we do this ?
Please help me!
Thank You!

You can use 'user segments' for this type of functionality. It will require that you send the segment as a parameter with your query. However, you may have issues with multiple segments as the system will require all to trigger not 'one of'.
A better solution would be a generic dimension which can be applied to your entire data set and then be used as a trigger without effecting the results, since implicit selection does not trigger exp manager rules.
Good Luck

Related

Policy based authentication taking into account what resources an user can work on?

I have setup my web api to use policy based authorization. I can have permissions like invoice:list, invoice:edit, invoice:delete, order:list, order:edit and so on.
Now, I need to return different sets of data depending on the user that is logged in. For example an user can retrieve all invoices (sales manager for example) and others just the ones created by them.
Would it be a good way to do it, add a bit more information to the claim like -> inovice:list:all, invoice:list:own, etc...? And add differnt filters to the final query depending on the "all" or "own" part?
What other alternatives can be implemented to solve this problem?
Cheers.

Ignore or not API endpoint parameters based on access level

I am working on an API endpoint that returns a list of products:
"api/products"
The endpoint accepts the following parameters:
page_size
page_number
Each product has a boolean property named IsApproved.
In the web application used by common users I always want to return only the Approved products ... On the web ADMIN application used by administrators I want to return all products, Approved or Not ...
My idea would be to add a new parameter (enumeration) named:
ApprovedStatus
And the values would be Approved, NotApproved and All.
On each API call I would check the user permissions ... If is admin I will consider the value on this parameter. If not then I will always return only approved products.
Another solution would be to have different endpoints ...
Any advice on which approach to take or is there other options?
The approval status is part of the product, therefore, in a perfect REST world, you don't want a different endpoint at all since you're accessing the same resource.
Then, for filtering a resource based on a property value, I think the convention is that if you specify that property as a query parameter it will only return those matching the value, and if not, it will return all of them, so I don't see the need to define a special ApprovedStatus parameter with some special values. Just query by isApproved!
Finally, about how to handle authorization. This, I think, should be handled at a completely separate layer**. If authorization is involved, you should have an explicit authorization layer that decides, for a specific resource and user, wether access is granted or not. This means the query would be triggered and if one of the resources generated by the query fails to be authorized for the user that triggered the query, it's taken out of the results. This accomplishes the behaviour you want without having any code that is checking specific users against specific query parameters, which is good because if tomorrow you have another endpoint that exposes this objects you won't have to implement the same authorization policy twice. Pundit is a perfect example on how to do this with Ruby elegantly.
**Of course, this approach retrieves data from the database unnecessarily which could matter to you, and also opens your endpoint up to timing attacks. Even then, I would consider tackling these problems premature optimizations and should be ignored unless you have a very good reason.
You're right about your ideas:
You can create a new endpoint just for admins, that will return all products
You can use a kind of authorization (e.g. Authorization Header) in order to check if the API is being called through admin or normal user. Then you can route internally to get all products or just IsApproved products.
You can add a proxy in front of your API to route to the right action, but it can also be achieved directly in the API but I think the second solution is easier.
Adding one more property is a bad idea.
In my opinion, adding another end point is very good. Because it will increase the protection in the admin end point.
Otherwise, since it is a web application, Simply set a cookie and a session to identify and separate the admin and user.
Going with the principle of least astonishment, I'd be in favour of adding a second endpoint for admin users. Such that you'll have:
GET /api/products (for regular users)
GET /api/admin/products (for admins)
This allows your code and API documentation to be nicely separated, and all of the admin-specific authentication details can live under the "admin" namespace.
The intention behind each API call is also clearer this way, which helps developers; and means that you can differentiate between admin vs regular usage in any usage stats that you track.
With ApprovedStatus, I think the specifics here don't matter much, but - considering what a developer using the API might reasonably expect / assume - it would be good to:
Ensure the ApprovalStatus parameter name matches the property name for "approval" that you return with each product object
Defaults to "approved" if it is not specified
Alert the user when an invalid value is specified, or one that they don't have access to
Bottom line: to answer your headline question - I think it's bad practice to ignore user input... sometimes. Design your API such that distinctions around when input can be passed in is very clear; and always alert the user if you receive input values that are technically acceptable, but not in the way that the user has requested, or for their access level. Ignoring values that are plain wrong (e.g. an argument that doesn't exist) is another story, and can be useful for future proofing or backwards compatibility.

Authorization in Pentaho

Is it possible to show the reports filtered by a field (say location) for a user in pentaho?
For eg:
UserA manages RegionA
UserB manages RegionB
UserAB manages RegionA and RegionB
When a user log into the system, (s)he should see the report showing the region only that they manage.
A same report format is shown for all users, but the content (or Query filter) differs for each users.
If this is possible, how to implement this?
Thanks for your assistance.
Yes; The proper way to do this is with session startup actions. These xactions allow you to set session variables which you can then access in your report. In this case you could define a location and use that in your query.
http://wiki.pentaho.com/display/ServerDoc2x/Using+System+Actions+to+Control+Data+Access
Alternatively you can access the username via a session variable too, so you could always put the logic in the query. but the nice thing about the session startup actions is that the logic is contained in one place incase it needs to change.
In your case as this is MDX (which i only just noticed from the tag) you'll have to generate a string that looks like a set of locations.

Grails Spring Security forcing user to a specific screen after successful authentication

Here is the scenario. I have two objects Users (with username/password) and UserInfo with rest of the data related to user. The Users is an old table with thousands of records and UserInfo is fairly new. I want to get as much UserInfo as I can when the user first logs in.
I'd like to force user to a custom screen after first login and ask for the UserInfo data. Once I get the "required" data in the new screen, I dont show it till the user voluntarily wants to fill in the data under "Profile".
Since there are multiple entry points to the application, I dont want to update all the controllers to check for this.
Is there a way I can use a Spring Security filter or something which is executed on successful login? I had a look at ApplicationListener<AuthenticationSuccessEvent> but it doesnt solve the problem as if I copy paste the link in the browser, it lets me go ahead to the destination without asking for "extra information".
In a nutshell, I want a check after each login which, if fails, user is not allowed to enter the application. No matter how he tries to get in.
In your Config.groovy, configure Spring Security's defaultTargetUrl and tell it to always redirect there:
grails.plugins.springsecurity.successHandler.alwaysUseDefault = true
grails.plugins.springsecurity.successHandler.defaultTargetUrl = '/userInfo/edit'
In your UserInfoController's edit action, you can check that the required fields are present (userInfo.validate() perhaps?) and if they are, redirect to wherever you like, perhaps '/', otherwise render the edit info view.
You can adopt what #doelleri proposed and enhance the rule by those steps:
run a batch task to assign a temporary ROLE_DISABLED role to each user who does not provide supplemental information yet. If the user already had some roles, save them in some property.
setup your authorization rule as that users with ROLE_DISABLED role only allowed to access /userInfo/edit.
in /userInfo/edit, if the user has a ROLE_DISABLED role, render the information input view, and resume user's role after it successfully updated its information. Otherwise redirect to '/' or the path it requested.

User-dependent BAdI implementation. How?

Is there any way to create user-dependent BAdI implementations? I mean that the BAdI has different implementations which are called depending on user which is logged and which calls the specific transaction.
Other scenario is to not call certain implementations for this user and to call for other user. Is is possible?
Now I'm using simple check
IF sy-uname = 'username'.
New BAdIs allow the GET BADI call to have one or more FILTERS parameters which can be used in the implementation definition to select different implementing classes. But these filter parameters must be provided by the code which calls the BAdI. When the standard code doesn't provide the username as a filter parameter, there is no way to choose an implementing class based on the username.
So when you want different logic for different users, you need to do this in your implementation code. But using the username to decide what to do might not be the most maintainable architecture.
I guess the reason why the BAdI is supposed to behave differently for a specific user is because that user has some special job in the company. What will you do when the person who has this position changes, or when he gets one or two other people to help them, or when he just calls in sick and someone else has to do his job? Do you want to transport a program change whenever that happens? But there are other options:
Different behavior by user group. You can read the user group from the database table usr02 (field CLASS)
Different behavior by permissions. Do an AUTHORITY-CHECK, and make the BAdI behave differently depending on the success.
Different behavior by user parameter. To read a user parameter in your program, use GET PARAMETER ID. The parameters of a user can be set by the administrators in the transaction SU03, by the users themself with the transaction SU3 (when they have the permission to do so) or programatically with SET PARAMETER ID.