I am writing a visualforce page that amoung other things allows creation of Queues. However I want to control whether the section is displayed depending on whether the user has the permissions required.
According to the docs: Creating Queues the user needs to have both permissions:
"Customize Application"
"Manage Public List Views"
I am querying the profile like so:
Profile profile = [
SELECT
PermissionsCustomizeApplication
//Was expecting: PermissionsManagePublicListViews
FROM
Profile
WHERE
Id = :UserInfo.getProfileId()];
However my problem is that I don't think the "Manage Public List Views" permission is exposed on the Profile object. Is the api name so different I am missing it? Does anyone know how to check for this permission in code?
I'm not sure about the name of the permission, but you could run an method to try and insert (and then delete!) a queue in an init method or similar, if it success then you know they have all of the relevant permissions required.
The snag here of course, is you may not want them to be able to delete queues (I'm assuming they work in the manner of the other objects in the system with respect to CRUD operations).
You cannot check for these permissions in code, and Lancey Snr's suggestion is probably the easiest work around. However, I personally don't like the idea of checking permissions by creating and deleting objects in the constructor.
I'd instead create a custom setting to track the Profiles (maybe as plain text) that are allowed to create profiles. The advantage of custom settings is that the administrator can update the custom setting when a new profile is created or an old one is deleted, or the permissions have been re-configured.
Use the custom setting in conjunction with the "with sharing" keyword in the controller code, and you can ensure that users who don't have permission to create Queues, won't be be able to create it.
Anup
I've decided to limit it just to people with the "Customise Application" profile option.
The reason being that this is the important profile option. The only reason people need the public list views options is because a new view is created for each new queue.
As I have discovered there is no crud security on the queue object in apex code. So restricting queue creation only to users with "Customise Application" seems like the safest and most flexible course of action.
Related
I'm currently working on a project where a user can have many roles, and each role has assigned one or many permissions. Permissions describe the actions that a user can apply to ressources. For example let's consider that I have three ressources that I can interact with using my API : users, books, payments.
I'd like to have all users able to update their personal informations like phone number... etc. This led me to give update permission on user's ressource for all users. But the problem is that I want them to be able to updates their own profiles only. Furthermore, some users have admin permissions and can change other users permissions, therefor they have another kind of update permission on user's resource.
So my question is : what's the best way to design the permission table. Below you can find my schema design. Thank you for your answers in advance.
User(firstName string, lastName string, roles Role[])
Role(name string, description string, permissions Permission[])
Permission(name string, effect 'Allow' | 'Deny', resource string, action string)
Well I am not entirely sure what you meant by resource and action. If you meant URI template and HTTP method, then ok. Otherwise you might need a different solution or somehow add parameters to your design if you want to allow or deny individual resources per id.
If we are talking about a REST API, which I assume, then you can do something like PATCH /api/v1/current-user/profile {...} for updating your profile and PATCH /api/v1/users/{user-id}/profile {...} to update somebody else's profile. If you meant controller classes and their methods, then you can do the same with two different controllers, something like CurrentUser.partialUpdate(params) and User.partialUpdate(params).
As of updating user permissions, I wonder how to do it, because you can update only role permissions and give or take away roles for the users in your model.
Another thing I don't understand that why do you need the allow|deny flags. If roles collide because users can have multiple roles or permissions collide, because you can both allow and deny the same thing, then how do you resolve it without a hierarchy? And if you don't have a hierarchy, then this flag is completely useless and just deny all and allow what is added to the role.
As of the one user multiple roles approach it is not a great idea, at least in places where people take security seriously a single account or at least a single session can have only a single role. Since this would make a lot of repetition I would solve this on a role level and make composite roles or support role inheritance. So for example the Administrator role would be the composite of the OwnProfileEditor and ProfileEditor sub-roles, which I would rather call Features or Capabilities or PermissionGroups rather than Roles.
Usually RBAC is not that flexible, so people tend to add per User Permissions to override Role Permissions. I would not do it, because you will end up with a mess if you follow that approach.
I have created an integration profile CORE_AKTANA_DI through which data for objects will be loaded into my Salesforce instance through a third-party user. I have provided "View All" permission for all objects to that profile. However, since this is a global Salesforce org, hence, there is data for other countries as well in this instance.
I want the user with the profile to see only data of France i.e with country "FR". In this case, my only choice is to:
Remove the "View All" permission of the profile from all objects.
Give the user a role such as "FR-Corp".
Create sharing rules for all objects with "Private" OWD and share with this role.
The problem is that since this is an integration profile, I cannot assign a role to the user with this profile. Also, it is not plausible to create sharing rules since there are a lot of objects with private OWD.
Same problem occurs by assigning the user to a public group, i.e a lot of sharing rules need to be created.
In this case, please suggest me the easiest possible options.
Actually, how to solve your issue is dependent on business process you are trying to implement. There are few ways:
sharing by hierarchy: setting proper roles and checking 'grant access using hierarchy'
sharing rules: setting proper sharing rules, owner/criteria based
manual sharing: using button
sharing using apex: using share object of any corresponding object
I think, this document will be useful for you.
I don't think what you say is correct:
"The problem is that since this is an integration profile, I cannot assign
a role to the user with this profile."
In my org we have a few integration connections. Each connection is anchored by a SF user license which has both Role and Profile. You should likely give the integration it's own user license and name the user something like "Integration (Fr)" Set the Roll up with appropriate hierarchy position, permissions and sharing rules and once you've done all the token resets needed set as API login only & password never expires. That should do it unless I'm missing something.
This is more of a best practices question. Our org currently has "public read" permissions on our org wide defaults for custom objects. We cannot make this private because of the way its working now for internal employees or rather we are trying to avoid this.
I am also creating a customer portal with custom visual force pages...where I display data using SOQL queries.
Is it a good idea to add a clause on the SOQL query to return only those records where the account id matches the logged in user's acount id?
I did it and it works fine...But are there any pitfalls to this method that I am overlooking?
Thanks,
Calvin
Per the Visualforce Documentation
Because standard controllers execute in user mode, in which the
permissions, field-level security, and sharing rules of the current
user are enforced, extending a standard controller allows you to build
a Visualforce page that respects user permissions. Although the
extension class executes in system mode, the standard controller
executes in user mode. As with custom controllers, you can specify
whether a user can execute methods in a controller extension based on
the user's profile.
I believe the idea being, as long as your classes are public with sharing then permissions should be enforced and records should not be returned that the user cannot see (same with fields on a record).
per the Apex Documentation
Apex generally runs in system context; that is, the current user's
permissions, field-level security, and sharing rules aren’t taken into
account during code execution.
Use the with sharing keywords when declaring a class to enforce the sharing rules that apply to the current user. For example:
public with sharing class sharingClass {
// Code here
}
Use the without sharing keywords when declaring a class to ensure that the sharing rules for the current user are not enforced. For example:
public without sharing class noSharing {
// Code here
}
Otherwise you would have to spend hours ensuring that the right permissions applied at exactly the right time for the right user. It would almost completely defeat the purpose of a visualforce page!
Let's say I have a Project model and a User model in a CakePHP application. Using ACL I can control if users can access to projects and/or to particular actions in a ProjectsController.
But I would like to go further and control whether a user is allowed to view a specific project, e.g. accessing a project with id = 3 using a URL like http://example.com/projects/3.
Is this possible with ACL as well or I have to develop additional checks on top of it?
Thanks!
To restrict access to specific values of a model, you'll need to use something other than ACL.
It'll be best to define a relationship between the users and projects, whether that's inclusive or exclusive.
You're probably needing a ProjectUser model (HABTM in Project and User) and a simple function in that model, maybe userAllowed($projectId, $userId), that checks that the user has been given access to that project.
I (finally) got ACL to work properly, based on group permissions. However when I create a new user (Users/add) it automagically.. I mean.. autoinconveniently creates a User ARO..
While this is not really a big problem, I would like my ARO table to stay as clean as possible. Just my groups.
How do I disable the automatic creation of a User ARO object when creating a new user through CRUD?
i had the same problem and, like you, i said to myself "its not a big deal as long as it's working"... but when i started to have more and more users and when i added new groups, i found that ACL was not working correctly.. If you're using a group-based permissions, you MUST ONLY have groups in your AROS table.
Brief, the documentation says that you need to add the bindNode() in your Users model if you want a group-based ACL, but what they don't tell you is that for group-based permissions your User model doesn't have to implement the requester behavior and you don't need the parentNode() neither. Remove those two and it should be ok.
I added a note on the documentation, i hope it gets published :)
Good Luck