AWS AppSync GraphQL with DataStore Custom Groups AUTH Linked to Objects - amazon-web-services

I have an iOS app using AWS AppSync through GraphQL, setup through Amplify, using DataStore for the local/offline cache and DynamoDB in the backend.
The use case is that the user creates an "entity" and in that entity they can have multiple groups such as "admins", "authors", "readers", etc.. Each of those groups have different permissions that exist within the realm of the "entity".
Each User could create multiple "entities" and therefore there are multiple groups that may have the same name but are separately related to "entities" and are only permissions for that entity.
To put it another way. A user creates a blog. That user is the Owner of that blog. That user then invites a friend to be an "Admin" of that blog. That friend is now a part of the "Admin" group for that blog. That "Admin" group is only pertinent to that blog. Other users may create blogs of their own and add their friends to be "Admins" of their blogs. But each of these "Admins" are actually in different groups (even if the group names are all called "admin").
So I don't think Cognito User Pool groups will work since there is a limit of 500 groups I believe? (Assume we can make more than 500 blogs and therefore more than 500 groups would be needed).
Preferably there would be the option for the Blog owner to create groups and give them any kind of name. But if needed the groups could be all named the same (admin, author, readers, etc). But as such, I see one of three options but don’t know how to proceed.
A table within my schema that handles the groups. I actually have this concept ready but am uncertain how to implement it with the #auth tag in the GraphQL schema.
Some way to link the “entity” with the Cognito group. So that user is related to group and group is related to entity and there is a check for all three using #auth in the GraphQL schema.
Some sort of custom code for authorization. I thought using lambda as the authentication method would work but #auth (rules: [{allow:custom}] is not supported by DataStore. Therefore am I looking at having to write custom VTL code? (Which I'm completely unfamiliar with).
I'm hoping there's a solution through standard auth means and working within the GraphQL schema. If not, sample code on how to achieve this would be much appreciated.

Related

Maintain Two Types Of User

So I have a requirement where I have to maintain two types of users.
A company and all of its users, to manage day-to-day work. And also create public data like showing a few items and related images and set availability for meetings and more.
Public user who can see the items, images. and can book the meetings.
Now for the first case, every user is created by official email and password as registeruser endpoint from rest-framework. there is user profile and other company data.
For the second type of user (public), I have to give access for social login as well as login by email/mobile (maybe).
I am confused as how to configure this in the best possible way. the company datas' are important.
Should I create both user types in the same database (differentiating by user types)? or should I use a seprerate database then how to fetch data from two databases (never done this)? Also to keep my datas safe from unauthorized access.
Or is there a better way to manage all of my requirements which I'm totally unaware of? Like a better approach.
Looking for an explanation from an experienced person.
Thanks
Maybe what you want is creating a custom User model (or even keep the default one) and implement permissions on views/ressource. This can be implemented by groups, for instance, the public group, in which everyone is (can be public or even no groups) and the private group.
Once you can differentiate between your users, you can add a reference to a ressource and its subressource to the group (ForeignKey on the group) and filters necessary queryset laters on your view. On certain view, you can also restrict some endpoints, through permissions.
Another way would be to use Object Permissions.
Anyway here are the ressources :
https://www.django-rest-framework.org/api-guide/permissions/ (and django-guardian for object-level permission)
and
https://docs.djangoproject.com/en/4.0/topics/auth/default/#permissions-and-authorization
Also, you can take a look on how it is implemented on a opensource project like Sentry: https://github.com/getsentry/sentry/blob/master/src/sentry/api/endpoints/api_applications.py

How can I integrate AWS-Congnito-Userpool-Group Logic into my React App?

I am working on a React Project and in there I want to use AWS Cognito for Role Based Authentication. My Project will be having multiple roles like Super User, User, Admin, Super Admin, etc. and to achieve this I have created multiple userpools. As in 1 userpool for each role and Everything is working correctly but turned out that I can achieve same functionality within single userpool by making groups in it.
So, The problem is that for now I am using 'aws-cognito-identity-js' library to authenticate users. but in that Library I couldn't find any code related to Userpool Groups and also I tried to find another library related to Userpool Groups but I couldn't find any. So, How can I integrate that Groups Logic into my React App?!
When you login to the userpool you get an ID-Token. The payload of this ID token also contains the groups the user belongs to.
let
[header, payload, signature] = idtoken.split("."),
jsonPayload = JSON.parse(atob(payload)),
groups = jsonPayload["cognito:groups"]
Of course you can also use your favourite JWT library (maybe even amazon-cognito-identity-js has something included) to verify and parse the ID token and extract the desired claims from it.
EDIT
amazon-cogito-identity-js cannot be used to manage groups during self-signup of a user. IMHO it would be counter-intuitive and a security flaw, that a user can add himself to a group (which probably has certain security implications in your app) without administrative intervention.
If you really want allow the newly created user to select which groups he belongs to, you can do that via a Post Confirmation Trigger on the userpool.
Add the desired groupname for instance as a custom attribute while signing up the user.
Once the user is confirmed the post confimation trigger (a lambda function) is executed. This lambda function has to have the necessary permissions to execute the AdminAddUserToGroup command.
Within the trigger (which receives the user's attributes as parameter) execute the mentioned AdminAddUserToGroup command.

WSO2 : application and users

I've created an application as "admin". Now, I create a "demo" user, and give him all roles and all permissions for this app. When I connect with "demo" I can't even see the application created by "admin".
Is this a feature ? or just a misconfiguration ? (but I don't see what config is left).
Yes, that's the default behavior. If you want to share applications/subscriptions among users, you have to enable the sharing feature. See Sharing Applications and Subscriptions docs for that.
Shared apps will be listed like this.
EDIT to make this the validated answer :
This whole paragraph from the documentation has to be written differently because it's wrong and very confusing. There is no "default" strategy of grouping, you have to alter the default configuration to activate it :
By default, the API Manager considers the organization name that you give at the time you sign up to the API Store as the group ID. It extracts the claim http://wso2.org/claims/organization of a user and uses the value specified in it as the group ID. This way, all users who specify the same organization name belong to the same group and therefore, can view each others' subscriptions and applications. The API Manager also provides flexibility to change this default authentication implementation

Django user groups only for permissions?

I'm a bit unsure what to use Django user groups for.
I have an application where every user belongs to a different organisation. The organisations don't have anything to do with read/write permissions. It's just a way to separate groups of users. Every organisation needs some additional fields, like a name, URL, and email address. New organisations will be added to the system over time.
Within every organisation, users can have different permissions for moderation and administration, for which I (also) want to use user groups.
My question: Should I use Django's user groups to define the organisations, or should I just make an 'Organisation' model with a relation to the user?
Nope. User groups are made for different reasons. You CAN use them to define organisations but I think you should think bit further ahead:
will the organisation require more fields than just name?
perhaps you will need permissions in the future to define users roles within organisations?
I'm sure you can come up with more things to think of. But if you answered yes to one of those questions then just create your Organisation model.
1) You need to add group from django admin side under group table.
2) And while creating new user, assign specific group to user using user_obj.groups.add(group_id). Or Let user select group at frontend.
and then user_obj.save()
in Group table, you can create organization
OR
You can create individual organization table and assign assign user to specific organization.

The use of various `auth` models

Other than auth_user, I have never used auth_group, auth_group_permissions, auth_permission, auth_user_user_permissions, and auth_user_user_permissions. What are the specific uses for each of these models? Is it common that one would not need any of these? If so, what would be the best way to get rid of them (doing a straight DROP TABLE or at the django-level)? Would there ever be a downside of removing these?
I'd recommend reading the User authentication section in the Django documentation. It describes the components of the auth system as:
Users
Permissions: Binary (yes/no) flags designating whether a user may perform a certain task.
Groups: A generic way of applying labels and permissions to more than one user.
The simplest use of permissions is to control the actions a certain user can take in the Django Admin site. You can also use permissions to restrict access to your own views using the django.contrib.auth.decorators.permission_required decorator.
When this is combined with groups you can easily assign the same permissions to a whole group of users.
The other database tables you mention (auth_group_permissions, etc.) store the relationships between users and permissions or groups and permissions.
While you may not be using these parts of the authentication system directly you are almost certainly using other code from django.contrib.auth that relies on them. If you're using an app you didn't write (whether it's part of Django or not) then it's probably a bad idea to drop the database tables that app creates.