In this post I will show you an extension for the Chimp component that will provide a transparent implementation of the security for the developers. With this extension the permissions metadata is no longer needed to be in the source code. The permissions will be loaded dynamically at runtime.
First of all, let me give you a short view of the architecture we are using in our applications:
- the main application navigation is made in a superTabNaviagtion: every conversartion (screen) is loaded in a separate tab.
This is done by the core of the architecture (our framework), every developer's team only have to take care of their conversations (screens), that will be loaded by the framework in a client workbench.
What I will do is, before every new screen (new tab) is loaded, I will call a service that will give the permissions (permitted actions) for that screen and then I will set those permissions to the Chimp component.
Of course, I will need a separate application to carry on those permissions actions of our components (that otherwise must to be written in the source code of the application as metadata), and this application will be managed by an administrator.
Finally, the only thing needed for working correctly is that every button or component to be securiced must have an unique id in the whole application. This could be done easily with naming conventions.
The next code is added to Chimp.as:
/** * Load chimp before the UIComponents are added with permission strings */ public static function load(permissions:ArrayCollection, metadataPermissions:Boolean=true):void { if(permissions != null) { _permissions = permissions; _permissions.addEventListener(CollectionEvent.COLLECTION_CHANGE, updateDisplay); } else { permissions = new ArrayCollection(); } _metadataPermissions= metadataPermissions; //add chmip system add handler FlexGlobals.topLevelApplication.addEventListener(Event.ADDED_TO_STAGE, processComponenet, true); } /** * @author s2o * ** * @param screenActions * */ public static function addScreenPermissionActions( screenActions:XML ):void{ var screenId:String = screenActions.@id; for each (var metadata:XML in screenActions.descendants("metadata")) { // the ChimpConstants.ACTION_REMOVE_CHILD is not considered var chimpAction:ChimpAction = getAction(metadata); chimpAction.parentId = screenId; ChimpActionCache.instance.addDelayLoadAction(chimpAction); } } /** * @author s2o * * Removes permission from cache * @param screenId * */ public static function removeScreenPermissionActions(screenId:String):void { ChimpActionCache.instance.freeCachedActionById(screenId); } //process ui object private static function process(obj:Object):void { if(obj is UIComponent) { if (_metadataPermissions) { processMetadataPermissions(obj); } else { processDelayPermissions(obj); } } } /** * @author s2o * * @param obj * */ private static function processDelayPermissions(obj:Object):void { var comp:UIComponent = obj as UIComponent; for each(var delayedChimpAction:ChimpAction in ChimpActionCache.instance.getDelayLoadActionById(comp.id)) { delayedChimpAction.comp = comp; doAction(delayedChimpAction); // for updates display on changes to the roles ChimpActionCache.instance.addAction(delayedChimpAction); } }*