AWS Amplify - update another user attributes - amazon-cognito

Is there a way I can update another user attributes using AWS amplify with cognito? I.e. when user reply to a post I want to change a rating of a person that started a thread. Or for this I will need a table in DB to manage it.
In docs i see that there is a method:
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#adminUpdateUserAttributes-property
but I dont see a way to use it in Amplify.

I have not seen any API of aws-amplify which can alter user attributes as admin.
Generally, it is good practice not to duplicate data or keeping data duplication minimal if unavoidable. In other words, keeping a single source of truth. Use Cognito as only for authentication, I mean obtaining JWT token.
Rating, user basic info, and role; keep those at your own data source.

Related

Check if user existed in cognito as federated user by using only email/username

I'm having trouble implementing a feature where I need check if a user does not exist or is existing in cognito but as federated user. The prior is done without trouble but I'm stuck on the latter without any clue. I went through the cognito and amplify documents but couldn't find any clue. Could there be a work-around or a function that I don't know about, any suggest is welcomed.
You can create a mutable custom user attribute on Cognito such as isFederatedUser and set this on user during user creation.
If this is not possible, you can call list-users and filter the identities attribute.

How to manage user updates and deletions in OIDC and SPA architecture

i am making a set of applications that share a common oidc provider (in my control), where the users will be created.
One of my applications is a stateless SPA "meeting" app where you can schedule meetings with other users, and you login purely by an OIDC token.
I am having a hard time thinking a strategy about the following
Should the "user" details be stored in the meeting app after a login? So let's say user A exists in the provider, then enters the meeting app. Should i save user A in the meeting app DB?
How to handle change of user details? Let's say user A changes name to User B in the provider. Until he logs in again, all the other users see him as User A still in the "contacts" list. What is the usual practice for solving this?
How to handle deletions in the provider. I need someway to signal that "deleted in provider -> deleted in app". Should i constantly poll the provider and get any missing users, create a push system, or is this just unneeded?
Thanks a lot in advance
That's actually a very good question and rarely explained well in online articles. Hopefully the below detailed notes help you with your solution. I have answered your questions at the end.
OAUTH USER DATA
Typically the core user data such as name, email etc belongs in the Authorization Server. It contains Personally Identifiable Information (PII) and changes are audited there. This is explored in further detail in the Privacy and GDPR article.
DOMAIN SPECIFIC USER DATA
This might include fields like a user's application preferences, and you may end up with data similar to this in your APIs:
Field
Description
id
A database surrogate key for the user
subject
The subject claim from an OAuth access token, which is typically a GUID or something similar
archived
A boolean flag set to true when a user is active in the app
field 1
A domain specific value
field 2
A domain specific value
To get OAuth user data within your applications your APIs can call the Authorization Server's SCIM 2.0 endpoint as described in this User Management article.
AUTHORIZATION AND ROLES
Interestingly, roles and application specific rights could be stored in either of the above data sources. You may want to start by putting roles in the OAuth data, but for cases where they are very domain specific and change often, I have found that storing them in my own API data works best.
DOMAIN SPECIFIC USER DATA AND ACCESS TOKENS
Sometimes you need to include domain specific user data (which might include roles) in access tokens. This Claims Article explains how claims can be looked up from external APIs during token issuance. This typically involves a REST call from the Authorization Server to one or more APIs, providing the subject value for which tokens will be issued.
CONSISTENT USER IDENTITY IN YOUR APPS
A user can potentially authenticate in multiple ways, such as default password / corporate login / social login. You may need to use some custom Account Linking logic to ensure that the subject field in the access token gets the same value in all cases. This prevents you ever creating duplicate users within your application.
USER INFO CHANGES
These are typically made by end users within an application screen, and your APIs then call SCIM endpoints to update the core OAuth data. A common case is when a user changes their name and / or email, eg if the user gets married. Note that the subject value remains the same after this edit.
USER ADMINISTRATION
In scenarios where corporate assets are used, an administrator typically provisions users, either individually or in bulk. This can be done via the SCIM endpoint. In some cases administrator actions may need to save data to both data sources - eg to create a user and set roles + application preferences.
USER INFO EVENTS
Sometimes your application needs to know about a user info event, such as new, deleted or changed users. This can be managed via Event Listeners, where an extension to the Authorization Server calls back your domain specific APIs when a user edit occurs. When a user is deleted in the OAuth user data you might then update the user's application state to archived.
DATA MIGRATIONS
Finally it is worth mentioning that the above also supports migrating to an OAuth architecture or between providers:
Get a combined view of the user data before migration
Insert all existing users into the new OAuth system via SCIM
Update the combined view of the user data with new subject values
Update your domain specific data with new subject values
SUMMARY
So to answer your questions:
Aim to avoid this because it adds complexity, though in some cases you may need to denormalise for performance reasons. The OAuth user data should remain the source of truth and the only place where edits occur to PII data.
Your meeting app would need to join on the OAuth user data and domain specific user data and present a list. This would probably involve caching a combined view of the user data.
See Administrator Events above. Your API should be informed of OAuth user data changes via an event, then your SPA would get current data on the next refresh.
When implemented like this you end up with simple code and a well defined architecture. Some providers may not provide all of these features though, in which case you may need an alternative approach to some areas.

Amplify authorization rule based on attribute value

I have a user, community and post type where a community can have multiple users and posts. The posts has an attribute called "visibility", if the visibility value is "private" only the users of that community can see the posts. If the visibility is "public" every user can see the post. Is possible to accomplish this using amplify and cognito? How?
Cognito has groups. You can create groups and add users into these groups. When your user authenticates they get a token, and the claims on that token can be used to confirm which groups they belong to.
Cognito Groups are really useful for controlling access to things like admin apis with an 'admin' group. However, if you're creating lots of groups of adding users in and out regularly, I would recommend implementing an application level feature (i.e. manage this in your database).
Cognito isn't as scalable as your application persistence is likely to be. It can be a bit slow and it doesn't come with nice features for managing your groups.
So yes, its possible to manage in Cognito, but I would recommend doing it with a database of some sort.

Use WSO2IS to configure user access to entities

I'm trying to implement WSO2IS for authorization. My understanding is that in the WSO2 realm, the concept of a permission broadly restricts a user's access to an action, or a resource. So, for instance, if my app is a bookstore, I could configure whether a user has "read" access to authors at large, and toggle their access to the GetAuthors() endpoint. However, I need to configure a user's access to certain authors. Is there a way I can store a whitelist of authors on a per-user basis? What I'd like to accomplish is to have a user call a GetBooks() endpoint and return only the books written by the authors that the user can access.
It sounds like one possibility is to store this information in an external datastore, and implement a custom PIP to read from that datastore.
Another possible option would be to create a custom attribute on the User type and store the whitelist of author IDs in an array on each user.
Is there a better way to do this? I'd prefer not to implement a custom external datastore just to store relationships between users and entity ids. Is it possible to do this with XACML and policies? Is it possible to have WSO2IS stick this information on a claim that is returned to my controller so that I can limit my underlying query based on the user's whitelist of allowed entity IDs?
AFAIU you need to maintain a claim to track the accessibility for reading. You can easily create a custom claim to track it by following the article[1]. In this way, you can refer to the custom claim at the controller to make further decisions.
You have to update this claim value for each user. For this, you can use SCIM API[2] by following doc[3] to extend the SCIM endpoint for custom claims.
[1]https://medium.com/#inthiraj1994/lets-add-a-custom-claim-to-oidc-in-wso2-is-d871e418d6b0
[2]https://is.docs.wso2.com/en/latest/develop/scim2-rest-apis/#/scim-20-api-definition
[3]https://is.docs.wso2.com/en/latest/develop/extending-scim2-user-schemas/#extending-scim-20-user-schemas

How to authorize user to update his own user data

Based on the information given at https://fusionauth.io/docs/v1/tech/apis/users#update-a-user it seems that any API key that allows access to this endpoint can update any user record.
I am missing a method of authorization based on a JWT for this endpoint so that any user can update his/her user record.
What is the recommended practice to handle this?
FusionAuth does not currently allow you to call the Update User API with a JWT issued to the user you're trying to update.
There are a couple of reasons for this. the first is that not all implementations would agree this is a safe operation for an end user to perform. The second is that because the custom data on the user and registration objects will be indexed by Elasticsearch. Elasticsearch creates a dynamic schema based upon these values which means it will expect the schema not to change.
For these reasons, and perhaps others, it is much safer to allow an API written by the FusionAuth implementor to handle this process.
That is all to say, you will want to call the Update User API on your end so you can control what is updated and perform any necessary validation on custom data.