I have a requirement regarding authorizations such that if user is Admin/Editor, user can read/write page.
If user is visitor , he can read only the same page.
I created authorization scheme IS_ADMIN where exists sql query:
select 1 from users where role_id in(select role_id from roles where name ='Admin')
Now i applied this authorization scheme on page.
In Read only, i selected function body,plsql and write:
If apex_authorized.is_authorized ('IS_ADMIN')
RETURN FALSE
ELSE RETURN TRUE;
END IF;
I applied this assuming this would make the page read only for the user which is not admin.
But because of the authorization scheme and error message that i set, i am simply getting error when i log in with visitor role. The same error message that i gave for authorized scheme.
What is the best way to apply multi authorization scheme in this case?
Apex: 20.2
One way to solve this is to create a security model that is based on roles and responsibilities (as done in ERP systems). A role is granted to a user (eg ADMIN, VISITOR, etc) and a responsibility is linked to application functionality (eg VIEW_EMP, EDIT_EMP). Responsibilities are then granted to roles or to other responsibilities. The authorization schemes are created on the responsibilities (the app is unaware of the roles).
Example for an EMP form: requirement is that VISITOR can see data and ADMIN can edit data
Create responsibilities: VIEW_EMP and EDIT_EMP and matching authorization schemes.
Role VISITOR has responsibility VIEW_EMP.
Responsibility EDIT_EMP has responsibility VIEW_EMP (so that whoever has EDIT_EMP automatically gets VIEW_EMP).
Role ADMIN has responsibility EDIT_EMP.
In the form you set the auth scheme of the page to VIEW_EMP and the auth scheme of CREATE/SAVE/DELETE button and DML Page process to EDIT_EMP.
So when a user with VISITOR comes to the form he gets the data but the buttons are hidden. When an ADMIN comes to the screen he sees all.
It sounds like you want the authorization scheme to be IS_ADMIN_OR_VISTOR which would return true if the user was either an admin or a visitor. That allows both admins and visitors to access the page. Your read-only logic would then mean that visitors would see the page as read only and admins would see the page as editable.
Related
I am building an intranet site for my organization with Wagtail and we are in the process of adding a knowledge base. The entire site needs to be restricted to logged-in users, but certain pages need to only be accessible to users in certain groups. For instance, only members of the IT group should be able to access the pages underneath the IT Knowledge Base page.
Currently if I set the top-level page to be accessible only by logged-in users, that permission is applied to every page on the site, and I am barred from setting more specific permissions on any child page. It is imperative that I be able to set more specific permissions on child pages.
I was able to find Wagtail Bug #4277 which seems to indicate that the logic for more specific permissions is implemented but not exposed in the admin UI.
I am not familiar with the inner workings of Wagtail yet, especially how Wagtail permissions intersect with Django permissions. How can I add more specific permissions to child pages?
You can restrict or allow users to view a site. You can also restrict or allow users to do some actions (maybe modifying an article).
To pass these restrictions or allowances django uses groups and permissions. Basically it all is based on permissions but sometimes you want to pass the permission to an entire group rather than passing permissions to users explicitly.
Therefore you could create your it_group. Then you would add the permission, let's call it it_permission to that group. When you then add a user to that group, that user then has all the group permissions. As said you don't need to organize these steps with groups. You could also add a permission, let's call it admin_status to a user directly.
When you build your views there are multiple operators that check for permissions of currently logged in user.
You could decorate your view with the permission-required-operator.
See the example:
from django.contrib.auth.decorators import permission_required
#permission_required('your_user_app.it_permission')
def my_view(request):
# only users with permissions can view this view.
Django and Wagtail are both awful at object authorisation.
For your case, it depends how tight you want to make the security, and how complex the authorization model is.
You can set permissions on a per page basis via the group edit page in the admin menu, any page below will inherit those permissions. The problem with this is that the least restrictive permissions apply and there is no deny option. If they have edit permission on a parent page, they'll have edit permission on the child page.
If you just want a superficial prevention to stop unauthorised people editing all knowledge base pages, you might look at using hooks to assess the permissions of the logged in user.
You can use before_edit_page to check before the page form is rendered for editing and redirect to a notification page if they fail, or use after_page_edit to prevent saving (not very friendly after the editor has spent some time on the page).
For before edit, for a simple one-off case and where there is a class for the KB page, where you want to allow only members of the IT Department and Site Managers groups to have access, it could be something like:
# wagtail_hooks.py
from django.contrib import messages
from django.http import HttpResponseRedirect
from wagtail import hooks
from kb.models import KnowledgeBasePage
#hooks.register("before_create_page")
#hooks.register("before_delete_page")
#hooks.register("before_edit_page")
def check_kb_permissions(request, page, page_class=None):
if (page_class or page.specific_class) == KnowledgeBasePage:
if not request.user.groups.get_queryset().filter(name__in=['Site Managers','IT Department']).exists():
messages.error(
request,
'You do not have permission to add, edit or delete knowledge base articles.\
<br><span style="padding-left:2.3em;">Contact support \
to report this issue</span>'
)
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/admin/'))
If the user fails, they stay on the same page with an error message in red banner at the top of the page.
You can build this out to a more complex authorisation model, matching user groups with models and permissions if need be, rather than the hard coded example above.
This doesn't affect CRUD permissions for programmatic operations, but if your concern is just the editor interface then this works.
In Amazon Cognito's User Guide, in the page “Configuring User Pool Attributes”, there is this paragraph (with added emphasis):
“If your application does not require a username, you do not need to ask users to provide one. Your app can create a unique username for users in the background. This is useful if, for example, you want users to register and sign in with an email address and password.”
I want to do precisely what the paragraph says: while users sign up, create in the background a custom user ID for them myself, because I need these IDs to follow a specific semantic format, that embeds tenant context into the IDs (something like “T01234#U01234567“, meaning “user U01234567 inside of tenant T01234”).
The users won't know of their custom ID, they will feel as they've signed up (and later signed in) with their emails (or through 3rd parties like Facebook and Google, if possible in this set up). But in the background I will create these custom IDs and store them in their username attribute in the User Pool.
The reason I want to store these iDs specifically in the username attribute is because it is un-mutable and unique, but most important because I will need to query Cognito's APIs (ListUsers, AdminListGroupsForUser, etc.) using these custom IDs as filter, to give my customers some user management capabilities. The username attribute is the parameter for these APIs. Therefore, I cannot use User Pool custom attributes here, since they are not accepted as parameters of these APIs.
The reason I post this Question is because, while the documentation recommends this as a possible setting, there is no specific information on how to set the user pools and sign up flow to support this specific use case.
What is the general settings layout of this? To start with, in the option “How do you want your end users to sign-up and sign-in?”, what do I have to put there in the scenario I described? If anyone can give any additional pertinent information, it would be very helpful, as the documentation feels somewhat opaque.
Thank you very much for those who've read this.
You probably will need to deal this in your frontend.
When your user start the sign-up process, you will need to generate the username based on your requirements and send the request to Cognito User Pool using that generated username + e-mail.
For Cognito User Pools this will be transparent because in the request it will receive the username, the password and the user e-mail. Off course you will need to allow login with e-mail and password.
If you don't want to do this in the frontend you can create a backend with public access that accepts a unauthenticated requests and performs this task directly in Cognito User Pool.
I created custom authentication, every user from table users can login to the app.
How can I restrict user if user has READ_ONLY role, that can only read app page and can't edit?
I have tables:
users(id, login_name, password),
roles(role_id, rname),
user_roles-junction table (users-roles),
privileges(id, pname),
role_privileges-junction table (roles and privleges)
You can control what a user can do in the app through authorisation schemes. It is not possible to make an entire app read only, so what you could to is the following. Suppose you have 2 authorisation schemas: READ_ONLY and EDIT. All the EDIT/SAVE/SUBMIT buttons and their corresponding page processes you then restrict to the edit authorization scheme. That way a user with READ_ONLY and not EDIT will only see the reports and forms but not be able to change any data.
I want make sign up and login on the base of their role there admin can add users and approved the request of other two user so that they can login.When user click on the sign up the user see sign up page accorading to their roll and same for login .
Django implements a pretty decent authentication framework inside it, so you already have things such as Users, Groups and Permissions to work on. All of those being managed easily by the admin page.
What you want to do is to assign a set of groups/permissions to a newly created user to determine its role and then build a frontend that manages the different kind of users in terms of templates. If you want an user to have itself validated before start using your page, refer to the is_active attribute of the User object.
Read for more information:
https://docs.djangoproject.com/en/2.2/topics/auth/default/#user-objects
I am currently trying to retrieve user events that grant admin or delegate privileges to accounts under our domain. I guessed such event names called GRANT_ADMIN_PRIVILEGE and GRANT_DELEGATED_ADMIN_PRIVILEGES is the one:
https://developers.google.com/admin-sdk/reports/v1/reference/activity-ref-appendix-a/admin-user-events?authuser=1
So, I filled the form in https://developers.google.com/admin-sdk/reports/v1/guides/manage-audit-admin?authuser=1#get_account_events to generate a request like GET https://www.googleapis.com/admin/reports/v1/activity/users/all/applications/admin&eventName=GRANT_ADMIN_PRIVILEGE or GRANT_DELEGATED_ADMIN_PRIVILEGES.
The result is 200 OK, but without any data in it (Of course, I actually granted Privilege to my coworker in last 2 months).
So, is it right to think GRANT_ADMIN_PRIVILEGE or GRANT_DELEGATED_ADMIN_PRIVILEGES is the event name I am looking for to audit granting activities? Or is there something I am missing?
You may want to visit Reports API: Admin Activity – Delegated Admin Event Names which details the admin activity report DELEGATED_ADMIN_SETTINGS type's eventName parameters and properties. For more information, see also the Activities: list method.