Module permission vs role permissions in silex - symfony

I'm quite confused about the ACL in symfony/silex and how I can make them work for me.
I've been thinking about a solution based on modules -> actions. However, reading about ACL, everything seems to be based on roles, which is to broad for the implementation I'm trying to achieve.
I will have users, and all users do belong to a role (admins, users, etc...). However, the role is more of a guideline of what you can do (as it sets the default permissions a user with that role starts with) that an actual set of actions a user can perform. The actions, are really based on the modules the system has and the permissions that are actually granted to any of the users to read, add, update of delete and any other verb outside of those.
So for example:
ROLE #1: Is an Admin
can read users
can post users
can put users
can delete users
ROLE #2: Admin
can read users
can post users
cannot put users
cannot delete users
Since I'm planning to have several diferente modules (users, payments, products, etc..), and each admin can have privileges granted or revoked, they will not fit the ROLE_ADMIN, ROLE_SUPER_ADMIN, ROLE_USER type of roles.
I was thinking something on the lines of ROLE_VIEW_USERS, ROLE_ADD_USERS, ROLE_EDIT_USERS and that a User will probably have 100 of those little roles and have voters for each controller that will decide if you can perform certain action.
Does this make sense?

You are confusing ACL and roles. They both have to do with permissions but they approach and function differently from one another.
Roles aren't inherently tied to a specific resource. On the other hand, ACL is, and that link is persisted. Users can be tied to resources (or appear to be so) through the use of voters.
https://symfony.com/doc/current/security/voters.html#creating-the-custom-voter
User-specific ACL, e.g. where a user has specific access defined PER resource, you'll need quite a bit more stuff.
Take a look at the SF cookbook:
https://symfony.com/doc/current/cookbook/security/acl.html
https://symfony.com/doc/current/cookbook/security/acl_advanced.html
OWNER/MASTER/OPERATOR CAN
Edit
View
Delete
Create
ALL RESOURCES (This is done using ROLES)
ROLE_USER CAN
EDIT OWN
VIEW OWN
DELETE OWN
CREATE
OWN RESOURCES (This part is done with ACL or voter)
Voters are effectively creating your own ACL and therefore there is no persistent permission unless you make one explicitly (At this point I would go ACL). The use case for ACL is basically the same as the use case for a voter, and choosing one vs the other is a matter of complexity.
The built in ACL info is coming from the database, but as per SF documentation: "It can contain tens of millions [of records] without significantly impacting performance."
Extremely simple? Could use a voter.
If you don't want to maintain your own rules (voters) for resources and don't mind the complexity of the ACL, or like that permissions are persisted + cached, you could use ACL instead.
Note that the complexity of the ACL is generally the following when creating resources (although this could be put in a service):
$aclProvider = $this->get('security.acl.provider');
$objectIdentity = ObjectIdentity::fromDomainObject($resource);
$acl = $aclProvider->createAcl($objectIdentity);
$tokenStorage = $this->get('security.token_storage');
$user = $tokenStorage->getToken()->getUser();
$securityIdentity = UserSecurityIdentity::fromAccount($user);
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
$aclProvider->updateAcl($acl);
For the previous scenario, you can use the ROLE_USER to make sure that the authenticated user is actually an actual user and not AUTHENTICATED_ANONYMOUSLY and the voter or ACL to make sure they can only edit their own resource, and override this if their ROLE is ROLE_ADMIN. (Assuming users are given ROLE_USER once they sign up)
Example in security.yml
# This could be done via #Secure(roles="ROLE_USER")
access_control:
- { path: ^/my/api/endpoint, role: IS_USER, requires_channel: https }
- { path: ^/my/admin/api/endpoint, role: IS_ADMIN, requires_channel: https }
Example in controller::action
// check for edit access
if (
false === $authorizationChecker->isGranted('EDIT', $resource) &&
false === $this->get('security.context')->isGranted('ROLE_ADMIN')
) {
throw new AccessDeniedException();
}
Here is another QA in StackOverflow that also provides some examples:
Symfony 2 ACL and Role Hierarchy
You can also use annotations for this stuff:
https://symfony.com/doc/current/best_practices/security.html#authorization-i-e-denying-access (It shows how one works vs the other).
Let me know if any part of this requires further explanation.
Thank you.

Related

How to check if user has permission to edit content using the eZ Platform Public API in PHP?

eZ Platform is a Full Stack Symfony based Content Management System (CMS). It adds a content repository and other features that allow users to create content. This is controlled by a sophisticated permissions system that allows finegrained control.
Normally these permissions are exposed through the user interface so that users can either perform certain functions or not. But how do I achieve this in my custom code, in Controllers or Console Commands?
Developers use standard services to interact with the repository. There are plenty of good examples of this in the CookBookBundle. One thing that is not covered by the examples in the bundle is how to check if a user has permission to do a certain function.
You can do this easily by using the PermissionResolver from the repository, for example:
$content = $contentService->loadContent(52);
$canEdit = $permissionResolver->canUser('content','edit',$content);
if($canEdit){
echo "Logged in user can edit object " . $content->getName();
} else {
echo "Logged in user can't edit object " . $content->getName();
}
This naturally applies to any commands and functionalities in the repository. For example, the content module has functionalities such as create, edit and remove.

Symfony 3 - How to change configuration values at runtime

What is the best practice way to handle changes to configuration parameters (kept in yml) that have to happen at runtime?
I am working on a site where the owner wants to change various settings in his admin back end.
For example, enabling/disabling the confirmation email and link sent by FOS User bundle when a new user registers for an account.
Thanks for your time
For those operations you need the use Compiler Pass.
https://symfony.com/doc/current/service_container/compiler_passes.html
Here sample Custom Compiler pass;
https://symfony.com/doc/current/components/dependency_injection/compilation.html#creating-separate-compiler-passes
Here is a good example for compiler passes; ( Usually using with service tags )
https://symfony.com/doc/current/service_container/tags.html

Multiple applications in the same Symfony2 application

This is quite a long question, but there's quite a lot to it.
It feels like it should be a reasonably common use case, so I'm hoping the Stack Overflow community can provide me with a 'best practice in Symfony2' answer.
The solution I describe below works, but there are several consequences I'd like to avoid:
In my local dev environment, if I have used the wrong db connection the test will work in dev but fail on production
The routes of the ADMIN API are accessible on the PUBLIC API url, just denied.
If I have a mirror of live in my dev environment (3 separate checkouts with the corresponding parameters.yml file) then the feature tests for the other bundles fail
Is there a 'best practice in Symfony2' way to set up my project?
We're running a LAMP stack. We use git/(Atlassian) stash for version control.
We're using doctrine for the ORM and FOS-REST with OAuth plus symfony firewalls to authenticate and authorise the users.
We're committed to use Symfony2, so I am trying to find a 'best practice' solution:
I have a project with 3 applications:
A public-facing API (which gives read-only access to the data)
A protected API (which provides admin functionality)
A set of batch processes (to e.g. import data and monitor data quality)
Each application uses a set of shared models.
I have created 4 bundles, one each for the application and a 4th for the shared models.
Each application must use a different database user to access the database.
There's only one database.
There's several tables, one is called 'prices'
The admin API only must be accessible from one hostname (e.g. admin-api.server1)
The public API only must be accessible from a different hostname (e.g. public-api.server2)
Each application is hosted on a different server
In parameters.yml in my dev environment I have this
// parameters.yml
api_public_db_user: user1
api_public_db_pass: pass1
api_admin_db_user: user2
api_admin_db_pass: pass2
batch_db_user: user3
batch_db_pass: pass3
In config.yml I have this:
// config.yml
doctrine:
dbal:
connections:
api_public:
user: "%api_public_db_user%"
password: "%api_public_db_pass%"
api_admin:
user: "%api_admin_db_user%"
password: "%api_admin_db_pass%"
batch:
user: "%batch_db_user%"
password: "%batch_db_pass%"
In my code I can do this (I believe this can be done from the service container too, but I haven't got that far yet)
$entityManager = $this->getContainer()->get('doctrine')->getManager('api_public');
$entityRepository = $this->getContainer()->get('doctrine')->getRepository('CommonBundle:Price', api_admin');
When I deploy my code to each of the live servers, I put junk values in the parameters.yml for the other applications
// parameters.yml on the public api server
api_public_db_user: user1
api_public_db_pass: pass1
api_admin_db_user: **JUNK**
api_admin_db_pass: **JUNK**
batch_db_user: **JUNK**
batch_db_pass: **JUNK**
I have locked down my application so that the database isn't accessible (and thus the other API features don't work)
I have also set up Symfony firewall security so that the different routes require different permissions
There's also security in the apache vhost to deny access to say the admin api path from the public api directory.
So, I have secured my application and met the requirement of the security audit, but the dev process isn't ideal and something feels wrong.
As background:
We have previously looked at splitting it up into different applications within the same project (like this Symfony2 multiple applications and api centric application. Actually followed this method http://jolicode.com/blog/multiple-applications-with-symfony2) , but ran into difficulties, and in any case, Fabien says not to (https://groups.google.com/forum/#!topic/symfony-devs/yneojUuFiqw). That this existed in Symfony1 and was removed in Symfony2 is enough of an argument for me.
We have previously gone down the route of splitting up each bundle and importing it using composer, but this caused too many development overheads (for example, having to modify many repositories to implement a feature; it not being possible to see all of the changes for a feature in a single pull request).
We are receiving an ever growing number of requests to create APIs, and we're similarly worried about putting each application in its own repository.
So, putting each of the three applications in a separate Symfony project / git repository is something we want to avoid too.

login with credentials fail with sfDoctrineGuard in symfony 1.4

So I've this application and have to grant access to type of people the admin and a little group of people who have to edit a little part of an module.
Lets say I've a module which has fields [A, B, C, D], and a group of people need to change the default value of some os the items that module represents, for instance C and D.
Now I've created the the groups, setted the permissions and assigned the test user to that group, editted the security.yml like this: credentials: [[admin, certificatore]] as i need to be an or. Try to access it's not letting me in. where i'm going wrong? myUser extends the sfGuardSecurityUser.
I've noticed that in DB the user, group and permission I've created are not present, but from the backend i can see them...
Have you tried deleting contents of cache folder?

Symfony 2 - Checking Action Permission with Roles and Groups

I'm new into Symfony 2 and I read some docs about ACL and the ROLE System.
I understood that I can use different Permissions on a Object with ACL.
But I need some different ( ? ) type of permission check, like in the static apache turbine roles / permission sets.
I want to use FOSUserBundle and using Groups.
The Groups should have permissions like
DOWNLOAD_PDF
DOWNLOAD_PPT
INVITE_USERS
and so on..
Stuff that does not have something to do with Objects but I have to check in Controller ( static ) and assign to Groups in an Userinterface.
I don't really found something about how to check those Permissions and assign them e.g. to Groups.
Is there something already exist? Or a best practice?
Or should I create for every Permission I need a ROLE?

Resources