Okta Api User Directory - api

Using the okta API, we're trying to display a simple staff directory. Basically we want to list all active users in a particular group on a web page.
Seems like it should be super simple.
If I use the user endpoint, I can get all users and filter by status to be active, but I can't seem to filter by group.
If I use the group end point, I can get all users in a group, but I can't seem to filter by status.
How should I be going about this?
Edit: Added my api calls
method 1
$filters = 'status eq "ACTIVE"';
$c = curl_init("https://wvuf.okta.com/api/v1/users?filter=".urlencode($filters));
method 2
$c = curl_init("https://wvuf.okta.com/api/v1/groups/xxxxGROUPIDxxxx/users");

Unfortunately, this is not possible in the current version of the Okta API. As you've surmised, you can either GET all users with an ACTIVE status and then iterate through them to get the groups for each user or GET all users for a specific group and manually filter by status.
The latter method may be preferable because it will amount to fewer calls (assuming there are more users than groups).

The List Group members (/api/v1/groups/${groupId}/users) endpoint does not support the filter query param
https://developer.okta.com/docs/reference/api/groups/#group-member-operations
One suggestion is to do some client side filtering (eg using jq etc)

The ListGroupUsers method in the Groups API for Okta enumerates all users that are a member of a specified group.
Have a look at this tool I created for a project I am on, okta-admin, wraps up the Golang SDK for Okta in an easy to use CLI (which effectively invokes REST API requests...)
okta-admin groups listusers $groupId
I have added the ability to pass filter arguments supported by the API or endpoint as well as a jsonquery argument where you can perform searches or projections client side.

Related

Has anyone set up an API for a group of users in BeyondTrust,

Has anyone set up an API for a group of users in BeyondTrust, and if so, will the members of the group be able to see and access each others passwords or do I need to create separate API Keys per each user?
I have not tried this as of yet, I do not fully understand the results of attempting an API for a group of users with in BeyondTrust Password Management systems, and I am afraid if I set up an API for a group of users, they will be able to view and utilize passwords that do not belong to them.
Is an API for a group even a thing, or do I have to set up API keys per user?
Password Safe users can use the API to do most of the functions available through the UI. They operate under the same security model regardless of access method, with the caveat that accounts need to be indicated as accessible via the API. This means that you might not be able access every account that you have access to through the UI, via the API but, it does mean you cannot access any account through the API that you don't have access to through the UI.

Azure ad graph api

I'm testing Azure Graph API.
and I'm trying to find an API that allows me to retrieve only users that are assigned to a specific app I created.
In app registration page, I gave a user.read.all permission, but the get user API gives me all users that are in the AD and not only that are assigned to the app I created. Should I change the permissions? or to access an another API?
Does anybody know what to do?
Thanks
Additionally, This object id should be based on service principal and not the application registration here.
You can retrieve the object Id from Azure AD->Enterprise Applications->Your app->object ID.
You need to have at least Application.Read.All and Directory.AccessAsUser.All for delegated permissions or Application.Read.All for application permission based on user or application context.
For specific details, you can add $select parameter to show only the displayName of the users assigned to the app.
https://graph.microsoft.com/v1.0/servicePrincipals/{object Id}/appRoleAssignedTo?$select=principalDisplayName
As a workaround you can use the below graph API to get the list of users.
https://graph.microsoft.com/v1.0/servicePrincipals/{ObjectID}/appRoleAssignedTo
Note: The above graph API gives the Object Types User and Service
Principle as well
As discussed in the MS Q &A Platform This endpoint currently does not support filters based on appRoleId. In fact, except that the id parameter can be filtered, the three parameters appRoleId, principalId, and resourceId do not support filtering. Similar issues have been raised before.

how to retrieve templates for different user accounts

I have one account in docusign which has 3 users for it. We have a requirement of retrieving templates of users for that account. The Template:List API is retrieving all the templates of the account. There is also one path parameter named user_id but it is not retrieving the templates of particular user account instead it is retrieving all templates.
Is there any way through Rest API we will retrieve list of templates of user account?
If there Please provide the Rest API details or link.
From my own testing, it appears you're right. This could be a bug, I'm not sure and I'll follow up but this may take time.
Two possible workaround.
Make the API call in the context of the user that you wish you get templates. Basically, you'll need to obtain an accessToken for the API for that user. With JWT that is very simple, just use the userID when you ask for the token (but you do have to get consent).
Filter the list of templates you get. The list does include information about the owner of the template (again, userID) but you'll get all of them and have to do the work to find the ones you want.
(Update 5/26/2020: confirmed with engineering this is a bug. It is tracked under TT-3290).
(Update 6/23/2020: bug was resolved, will be deployed shortly)

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.

CRUD only for the organization the user belongs to

Background
I'm building a application where all users belongs to a Organization. I only want the user to be able to Create/Read/Update/Delete records in the Organization they belong to.
I'm using sails, but I'm looking for Connect/Express-based, or a standalone answer as sails-permissions node module is unmaintained.
Question
How can one implement a authorization that allow CRUD only for the organization the user belongs to?
We are also not relying on sails-permissions. In our app, users can be members of multiple orgs.
We are using auth0 for all authentication activities, i.e. every request must include a jwt that is included in the request header. The jwt includes userId, orgId and role.
Sails policies decode the jwt and attach userId, orgId and role the the req object for all later checks.
Every model has the property orgId - we are using MongoDB.
Every controller, db operation, etc. adds this verified orgId to the query. Actually we have a small pipeline preparing the query: we add the orgId, in update cases we filter out unwanted property updates, etc.
This approach does not require additional db calls for separation of tenants.
Some models have specific access requirements per individual RECORD. Here we store allowedUser properties (one for read, one for update, etc.) on exactly this record and we extend the query once more so that only records are returned or updated or Xyz where the current user is included in the applicable allowedUsers property.
This approach also does not require additional db calls. This leverages MongoDB-specific query features, though.
We currently do not have ACL-like requirements which would be right between the 2 approaches I described above (re access control granularity).
You'll need to intercept each request using middlewares
combine them with a role system by checking if a certain token is present on request headers and in a acl map and finally, if the token is present in the acl map, see which permissions are related with this token.