Zend Framework: Can you do ACL without the plugins directory? - zend-framework

I am having trouble understanding the rules to ACL in ZF and the docs aren't clear. I am using a common Zend library for all websites. So far no problem but now every demo or example says that you should place the ACL class (acl.php) in the libraries directory as a plugin. Zend/Library/My/Controller/Plugin/.
I don't want to do this because it defeats the purpose for sharing a common framework directory.
Has anyone done or have any ideas about how to accomplish ACL using individual acl.php class files for each website/web application?
Thanks

You don't have to place the acl.php in the libraries directory as a plugin. The autoloader will load the class just fine, the trick to Zend_Acl is just priming an instance of the class with your roles and resources.
It's been a little while since I touched Zend Framwork but I'll try to steer you in the right direction.
In your bootstrap, create the Zend_Acl object
$acl = new Zend_Acl();
//see documentation on how to add roles and resources
Now create a Plugin folder inside your Controller directory, this will allow you authenticate with your acl.
Inside there create new class that extends Zend_Controller_Plugin_Abstract give it the correct class name to be picked up by the autoloader.
Store the acl you create in the registry and in your plugin override the preDispatch method, from here you have access to the request and the acl (from the zend registry) you can validate as needed. (Some people have controller/action as resources others models. It's quite freeform.
Register your plugin with the front controller.
$frontController->registerPlugin(new My_Controller_Plugin_Acl());
This is probably what the other tutorials are suggesting (or variants of this), it can just be a little confusing sometimes.

You should never add files to your Zend library directory - do you have any links to tutorials recommending this? The files should either go in the library directory under your application's namespace, giving you a structure like:
application/
library/
Zend/
(ZF files)
Foo/
Controller/
Plugin/
...
or in application/plugins, application/controller/helpers or somewhere else depending on the approach you are taking.
Edit: it sounds like a controller plugin is what the tutorial is recommending, in which case you'll want a class like Yourapp_Plugin_Acl (replace 'Yourapp' with your app's namespace) which would live at application/plugins/Acl.php.

Ultimately, you can place it anywhere you want as long as your autoloader is sufficiently configured to find it. And precisely how you use it depends upon what resources and privileges you are trying to protect.
But think you are confusing instantiating your ACL and querying your ACL.
You will most likely instantiate/populate your ACL object during bootstrap and store it in the Bootstrap registry or in the Zend_Registry singleton.
If your resources are controllers and your privileges are actions, then it is common to intercept the dispatch cycle with a preDispatch() plugin that queries your ACL object.
So, we are really looking at two different classes/objects:
One is the ACL itself, extending Zend_Acl. This one could be named Application_Model_Acl and placed in the file application/models/Acl.php.
The other is the front controller plugin. This one could be named Application_Plugin_Acl and stored in the file application/plugins/Acl.php
[Note that both of these presume that we are using an application namespace Application. Also, note that both of these are project-specific.]
Of course, the plugin as described needs to be given the ACL object in order to do its job, so your Bootstrap might have a method like this:
protected _initAclPlugin()
{
$acl = new Application_Model_Acl();
$plugin = new Application_Plugin_Acl($acl);
Zend_Controller_Front::getInstance()->registerPlugin($plugin);
}
But remember, this is only one way to use your ACL. In some cases, your ACL might not be limited to just controllers/actions. In that case, you might need to pass your ACL object to other models/services that query it, as well. In that case, you might have a separate method in your Bootstrap to create your ACL object and store it in the Bootstrap registry. Then your controllers - or even a dependency injection system - can grab it from there and pass it through to whatever downstream models/services might need it.
[You know, looking at my answer, it's not really different from that of #linead. Same idea, different words, but he totally got in first.]

Related

Clone rep:policy on AEM

I am currently working on with a solution that would be able to clone/copy/backup my existing rep:policy. 'Cause when we do some jobs it accidentally removed. I am trying to apply this kind of fix, but am failing to. It says it is an invalid path.
javax.jcr.security.AccessControlException: OakAccessControl0006: Isolated policy node. Parent is not of type [rep:AccessControllable]
final Workspace ws = session.getWorkspace();
ws.copy("/etc/commerce/products/abccompany/TvPackChannelMap/rep:policy","/tmp/nxt/TvPackChannelMap/rep:policy");
Are there other ways that I can be able to take the rep:policy thru code?
You need to make sure that your job does not touch the permissions or the rep:policy, this is the best way forward for you.
The exception could be because of /etc/commerce/products/abccompany/TvPackChannelMap/rep:policy does not exist or the user whose session you are using does not have read access to the node.
Make sure the path is correct, copy paste it to your CRX/DE to make sure it exists.
I have tried to use your code to copy a rep:policy from one node to another, works fine. But I would not* recommend copying permissions that way. The best practice is to use the Access Control Management API for all things permissions.
You can check, install and use the access control tool from netcentric. It offers a jmx interface for exporting AC entries and maybe also some APIs you could use to implement your custom solution.
The Other approach is to retrieve the ACL permissions through the query language.
For example, SELECT * FROM [rep:ACL] or SELECT * FROM [rep:ACE] where [rep:principalName] is not null should give you the results.
For more information, I would recommend you to check the ACS commons ACL Packager Implementation which is available on GitHub.
Reference Link - https://github.com/Adobe-Consulting-Services/acs-aem-commons/blob/master/bundle/src/main/java/com/adobe/acs/commons/packaging/impl/ACLPackagerServletImpl.java

sails.js blueprints override as hook

A while back I asked how to override sails.js blueprints (CRUD blueprint overriding in sails.js)
With v0.11 of sails.js we now have blueprints (and they are awesome :)).
Is it possible to turn off the current blueprints and install a new version of them as a hook?
This issue comment (https://github.com/balderdashy/sails/pull/2173#issuecomment-54165548) from #sgress454 seems to indicate it is/was in the works, but I can't find anything more specific about it.
I know I can override by creating an api/blueprints folder, but it would be easier for my users to consume via an npm install.
You are right, this is possible.
It is actually what happens in Sails's core here : https://github.com/balderdashy/sails/tree/master/lib/hooks/blueprints
Default blueprints are loaded like an Installable Hook would be.
You can just go ahead and copy that MIT licensed code and then replace the content of the actions directory with your own blueprints.
After that, update the object BlueprintController in index.js to make sure it points to your files.
Finally, all the magic happens in the extendControllerMiddleware method. You can see the code will go through each controller to inject your blueprints. The key point here is the replace the call to _.defaults with _.assign because your sails hook will want to overwrite defaults blueprints and not simply add them if they do not exist.

Migrate custom Facebook util library to Yii framework

I have a facebook app developed in plain PHP, I'm migrating the app to YII framework.
The thing is that I use a class call "utilsFacebook" where I have the object facebook(of the fb sdk) and all the methods that I need to get data from facebook, getUserId, getUserFriendList, etc.
I don't know how to handle all the operations that I do in utilsFacebook with Yii.
Create a controller with the functions of utilsFacebook is the correct think to do?
Every time that I instance the controller would create a new Facebook object, Should I store that object in a SESSION to get a better performance or is a bad idea?
Q. Create a controller with the functions of utilsFacebook is the correct think to do?
Having done a facebook app using yii as the framework, i would recommend you to make this library either a component, or an extension.
But definitely don't put these functions in the controller directly. Whenever a controller needs them call the functions using your custom facebook util class.
Components can be put in the folder: projectrootfolder/protected/components
Extensions can be put in the folder: projectrootfolder/protected/extensions
If you don't believe that either of these make semantic sense, you can always create a new folder within protected, say utils and put the class there. However i think extensions is the best way to go.
Q. Should I store that object in a SESSION to get a better performance or is a bad idea?
I don't think it's necessary to store the object in a session, because there will be no visible performance gain. Further you'll complicate your code unnecessarily.
What i had done was, created an app level component and used this component throughout the app, in any controller.
Example:
In your application's config, protected/config/main.php :
'components'=>array(
'fbHelper'=>array( // gave the component this name
'class'=>'ext.utils.FacebookHelper', // had stored the helper class in extensions/utils folder
'parameter1'='somevalue',
// more parameters
),
// standard yii app components
),
This will allow you to use the component like this: Yii::app()->fbHelper->getFriends();
Take a look at the facebook-opengraph extension, which could help you, on the way.

how to load models from another module in zend framework?

i am developing an application using zend framework.
i have two modules, admin and default, and each of them has their specific model directory.
i want to know, if i can instantiate a model in admin module from within default module and if this approach has problem regarding to the MVC model.
thx in advance.
So long as youve set up the Zend_Application_Resource_Modules or something pretty equivalent all you models should be registerd with the autoloader via the Zend_Application_Module_Autoloader that the modules resources registers. In short, if you follow the default way of doing things, then Models from all modules will be set up for Autoloading in the bootstrap phase.
About Zend Application and Resources
You can call get_class(): http://us3.php.net/get_class
There's possibly a more zend like way to do it, but I don't know. Check the docs.
What about call via object?
Like inter-connect two model functions in controller.
$contacts = new Model_DbTable_Contactsmdl(); // Model file in contact module
$update_id = $contacts->updateContacts($cn_id', $responsearray);
This code inside my syncController.
So you can handle admin / model function in default / controller.

Zend Framework and switching view script paths

I have a problem. Basically, depending on whether a user goes to /es or /br or /cn etc on our website, we have different language template files. So far, we were using a custom templating engine to make this work, but are making a switch over to ZF. I can't seem to figure out how to get ZF to look for a view script in say cn/about-us if the language varuable is cn.
I can't (don't want to) use Zend_Translate for this because we have way too many translated template files and it's just not feasible using Zend_Translate for bazillion different files with multi-paragraphs of Chinese/Korean/Japanese, forgetting for a second that I don't speak those languages.
Can anybody help me?
You can write a controller plugin and use it's routeStartup() method to alter Zend_View settings (path to where your view scripts are located) and change the request uri before routing starts.
class My_Controller_Plugin_LanguageSwitcher extends Zend_Controller_Plugin_Abstract
{
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
// examine the $_SERVER['REQUEST_URI'] and look for your language identifier
// fetch the View and set appropriate view scripts path using setScriptPath() method
// strip the language identifier from your REQUEST_URI
// change the request uri using $request->setRequestUri('your-new-uri-without-the-language- identifier');
}
}