Notify user about not allowed results via ASPECT pfcg_auth? - authorization

In "classic" ABAP authority checks, you would sometimes loop over a result list. If for at least one item the check fails, you'd notify the user about this and show only the items he's entitled to.
My question is: How would you do this in CDS using the pfcg_auth aspect?
For example:
define role my_role {
grant select
on vbak
where ( vkorg ) = aspect pfcg_auth ( v_vbak_vko, vkorg, actvt = '03' );
}
How would you tell that the selection found say 50 sales orders but the user is only authorized to display 40 of them?

For CDS view select, there is a syntax that you can select bypassing the DCL WITH PRIVILEGED ACCESS
You can select count(*) for the data in the database WITH PRIVILEGED ACCESS. if the numbers do not equal, you can raise the message.

Related

Query Salesforce users and their permission sets (SOQL)

i'm trying to run an SOQL query on salesforce to get all users and their permission set id.
it is important the list return will be by user not by permission sets, meaning if i have 1000 users i will get back 1000 records and for each record the user attributes like email etc + permission sets list of Id's assign to him
SELECT+id,PermissionSet.id+FROM+User i tried finding the relationship field name but i'm not so familiar wtih salesforce, please assist
https://developer.salesforce.com/docs/atlas.en-us.238.0.object_reference.meta/object_reference/sforce_api_erd_profile_permissions.htm
The table you're looking for is PermissionSetAssignment
Top-down:
select id, email,
(select permissionsetid
from permissionsetassignments
where permissionset.isownedbyprofile = false)
from user
or bottom-up
select assigneeid, assignee.email, permissionsetid
from permissionsetassignment
where permissionset.isownedbyprofile = false
order by assigneeid

How to display different interactive grid queries, depending on user privileges

I use Master-Detail page. I want to display whole table only for user who is an administrator. For the user who isn't the administrator, I want to display sql query which will be restrict MD view.
I tried to create another one master detail on same page which is visible only for users without Administrator role. And first MD is not visible for them.(I used Server-side Condition) Is there exist some other way to display different query, depending on user role.
I hope I explained the problem clearly. Thanks in advance
Have a look at the package APEX_ACL, you can use the related views in your where clause.
Example:admins see all rows, other users only see the row for KING
SELECT *
FROM emp
WHERE
-- user is admin ?
( EXISTS ( SELECT 1
FROM apex_appl_acl_user_roles
WHERE application_id = :APP_ID AND
user_name = :APP_USER AND
role_static_id = 'ADMINISTRATOR'
) ) OR
-- user is no admin
( ename = 'KING' );

MS Access SQL code - query issue with NOT IN

I'm trying to find out which partners has not paid the monthly tuition in a particular month.
I have a table called Socios containing all partners names SocioNome and another table called RegistroPagamento contaning all payments done (This particular table is fulfilled by a form where the user input the Partner Name, Amount Paid and which particular month/year the payment is related to).
I have created a query where I used the SQL code below:
SELECT [SocioNome]
FROM [Socios] NOT IN
(SELECT [SocioNome] FROM [RegistroPagamento] WHERE [MesBoleto] = [Forms]![Selecionar_MCobranca]![TBoxMes] AND [AnoBoleto] = [Forms]![Selecionar_MCobranca]![TBoxAno]);
[Selecionar_MCobranca] is the form I have mentioned before and the [TBoxMes] & [TBoxAno] are the combo boxes from the form which the user can select the month and the year the payment refers to.
When I run the code, a error message pops up indicating that there is a FORM clause syntax issue, and I don't know exactly what is causing the problem.
NOT IN is a comparison operator in the WHERE clause. It does not belong in the FROM cluase. I strongly recommend using NOT EXISTS instead. The idea is:
SELECT s.SocioNome
FROM Socios as s
WHERE NOT EXISTS (SELECT 1
FROM RegistroPagamento as rp
WHERE rp.MesBoleto = [Forms]![Selecionar_MCobranca]![TBoxMes] AND
rp.AnoBoleto = [Forms]![Selecionar_MCobranca]![TBoxAno] AND
rp.SocioNome = s.SocioNome
);
NOT IN returns no rows if any row in the subquery is NULL. To protect against this, just use NOT EXISTS. It has the expected behavior in this case.

Setting a column value for only one user depending on results

I'm currently playing around with SQL and trying to find the best way to accomplish this:
I currently have a user table that has a user_id, organisation_id, registered_datetime. There are
a number of users in this table with different organisations. There may be 3 different users in
1 organisation, or 1 in 1 organisation, etc.
I have added a new column called admin_user and I am trying to string up an SQL statement together
to update the admin user column. There can only be one admin user per organisation, and I want
the user who registered the earliest for that organisation to be the admin.
I could do this manually but it would take time if I had a lot of users. What would be the best
way to accomplish this?
EDIT:
So I have a number of users like this with the columns. The ones highlighted are the users that has registered the earliest. I want to be able to set those users as an admin user. The only admin user within their organisation and set the rest to 0. 1 (Admin) 0 (Not Admin)
This SQL query will mark users which registered_datetime are lowest in its organisation_id as admin.
UPDATE users SET admin_user = 1
WHERE user_id IN (
SELECT u.user_id FROM users u
WHERE u.registered_datetime IS NOT NULL AND NOT EXISTS(
SELECT 1 FROM users iu
WHERE iu.organisation_id = u.organisation_id AND iu.registered_datetime < u.registered_datetime
)
)
You might want to update all users to admin_user = 0 before this code, so all your users will have their values set.
One caveat here, if two users in one organisation were registered in exact same time, then both of them will be marked as administrators.
Update
I have added u.registered_datetime IS NOT NULL into the WHERE clause to filter out users with NULL in registered_datetime.
MSSQL
In MsSql server I usually solve this problem a in another way, by using ROW_NUMBER():
WITH base AS (
SELECT user_id, ROW_NUMBER() OVER ( PARTITION BY organisation_id ORDER BY registered_datetime ASC ) AS rn
FROM user
WHERE registered_datetime IS NOT NULL
)
UPDATE user SET is_admin = 1
WHERE user_id IN (
SELECT base.user_id FROM base WHERE rn = 1
)
This is too long for a comment.
You are describing three different tables:
Users
Organizations
UserOrganizations
The last has one row per user and per organization. This provides the mapping between the two. This can be called a "mapping" table, "junction" table, or "association" table.
How you implement one admin per organization depends on the database you are using.
You do not need the admin_user column. You need a column isadmin.
When a user is registered, if he is the first in the organization, then the isadmin column has the value 1, otherwise 0
Also, you can use the AAA query to find the administrator
SELECT `table`.`user_id`, MIN(`table`.`registered_datetime`) WHERE `organisation_id`=...

Can you tell me a better approach in designing a table for banned users than this?

I am designing a web application and I need to give the administrators and moderators the right to allow and deny other users access to the application. I am thinking of having a table with the following columns:
OperationType (Ban / Access regained).
BannedUser
User (admin/mod that gave access or banned another user)
EventDate
Reason (optional)
I can just have a table, storing all banned users, but I want to keep track of what is actually happening in the app and make sure that the administrators and moderators are not misbehaving as well.
So, If my table doesn't include an OperationType column, a list of all the banned users could be retrieved as simple as writing the following query:
select BannedUser from UserBan;
But if I leave the table with an OperationType column, as shown above, my simple select query could become something like this:
select o3.BannedUser
from
(
select o1.BannedUser, max(o1.EventDate) EventDate
from UserBan o1
group by o1.BannedUser
) o2, UserBan o3
where o3.EventDate = o2.EventDate and
o3.BannedUser = o2.BannedUser and
o3.OperationType = 1
Assume that OperationType = 1 is ban.
So, can someone give me a better solution for my case? :)