ZF2 ACL check link in view - zend-framework2

I have set up my roles, resources and permissions in my bootstrap, and in my layout have set up a navigation menu based on this, and this works.
What I am attempting to do now is create an admin panel with edit / delete links IF the current logged in user has those permissions. e.g. I may have multiple roles that can view a list of cms pages, but only certain roles can edit a cms page, and only certain roles can delete a cms page.
At the moment I am just checking if the user is logged in:
<?php if($user = $this->identity()): ?>
<?php if($user['role'] == 'admin'):?>
Delete
<?php endif;?>
<?php endif;?>
How do I check the permissions of the current user role for the specified resource from the view for an arbitrary link (as above)?

The ACL view helper is injected into the layout, so to check if a role has access to a resource, we can call $this->layout()->acl->isAllowed.
In this code snippet, we check if the user is logged in ($this->identity() returns false if not logged in, or an array of details if logged in), then if the user has 'delete' permission to the resource:
<?php if($user = $this->identity()); //is logged in? ?>
<?php if($this->layout()->acl->isAllowed($user['role'], $resource, 'delete')):?>
Delete
<?php endif;?>
<?php endif;?>
isAllowed signature is isAllowed($role = null, $resource = null, $privilege = null)

Related

Determine Action for Route in Symfony 1.4

I'm writing an extension of url_for which will check that the logged in user has the appropriate credentials to access a link to a route before rendering said link.
I have determined how to get the Action from module/action strings, and successfully check the credentials required. But I can't find a reliable way to get the appropriate Action from the name of the route, whether a named route or one derived from pattern matching e.g.
home/index => module: home, action: index
#home => module: home, action: index
I suspect I need to copy code from sfRouting, as I can't find a public method in Symfony to do this. Is there a better way?
I tend to just use the route name for stuff like this:
<?php $route = $sf_context->getInstance()->getRouting()->getCurrentRouteName() ?>
<?php if ($route == 'home'): ?>
<p>hello</p>
<?php endif ?>

How to update Login Info

I have an ajax enabled login form, which makes an ajax call to the server to login. If successful, it sets the Session object with the username. Then when it completes, the OnSuccess event calls a partial view update which then shows the user name.
This works fine in VS. However, when deployed it does not. I think the issue is that the Session is not getting updated fast enough for the second ajax call to be able to see it. If I do a page refresh, then the username IS updated.
Is there some other way I should be doing this? The only thing I can think of is make a database call to see if the user is logged in, instead of relying on the Session Object.
This is the Partial view:
<ul id="LoginLinksPartial">
#{ var customer = (NTC.PropertySearch.Models.Customer)Session["Customer"];}
#if (customer!=null)
{
#customer.DisplayName
#Html.ActionLink("Logout", "Logout", "Account")
}
else
{
<ul>
<a onclick="openLoginWindow()">Login</a>
<a onclick="openRegisterWindow()">Register</a>
</ul>
}
</ul>
put as an answer so question can be resolved:
Client has not yet sent session back to server in order to create the session handshake.
recommendation in this instance is that ALL shoppers have a session when first visiting the website, if login occurs ( within popup ) the session is simply updated with the users REAL ID, and if needed, the basket rows are also updated with the new session ID or User ID.

Is my approach of giving access to users correct?

I am applying spring security on my jsp page, I need to show different parts of the page to users with different roles all the roles are as following.
All authenticated users >> Edit and Add New
Admin > Delete and Edit and Add New
Anonymous > Add New
<sec:authorize
access="isAuthenticated()">
Code of add new and edit buttons
</sec:authorize>
<sec:authorize
access="hasAnyRole('ADMIN')">
Code to add new, edit and delete buttons
</sec:authorize>
<sec:authorize
access="isAnonymous()">
Code to add new
</sec:authorize>
I am wondering if there is any easier method, in this case, if I want to modify access of a specific role I have to change its access rules in security.xml file and every page that I have set the role access.
For example, lets say I want to unable Admin role to access delete button then I have to change the code of security.xml and all the JSP pages that admin role was authenticated to view delete button.
Is there any easier method to do it!?
There can be a solution by using rights set which can be contained in role object as a collection.
After this implementation you can check the right permission for showing buttons and if you want to change anything in your security architecture, you can easily manage this by granting or revoking the rights from related role.
An example of this can bee seen in the link below.
http://en.tekstenuitleg.net/blog/spring-security-with-roles-and-rights
I don't think there is a built in solution for this. You could set up a fine grained role system assinging like a edit role, a delete role and so on. Then you can assign these roles more freely.
If you want to keep it easy for the user (like still only showing admin and user role) you might have to mask the actual roles behind a mapping between the roles and the titles shown to users.
Another approach would be to set up global parameters for each action (edit, delet, etc.) in which you specify the roles that shall be allowed for the action. This way you wouldn't hardcode the roles into your application but map them through the global parameters.
Looking forward to see if someone else comes up with a better idea.
Edit to specify the approach of mapping by global parameters (refined the mapping would be stored in a db but that is getting from an ad hoc solution to implementing an ACL):
With global parameters I just meant something like a rightsMapping.properties. In this file you would map something like that:
right.edit=ROLE_USER, ROLE_ADMIN
right.edit=ROLE_ADMIN
etc...
After that you can just insert the rights into the jsf pages using something like this:
<f:loadBundle basename="rightsMapping" var="rights"/>
....
<f:CommandButton name="edit" .... rendered="hasRole(rights.edit)"/>
This is a pretty easy hands on solution which can be refined by using for example a mappings table in the DB, a Bean evaluating access rights, etc. But the basic idea of mapping the fine grained rights to the roles stays the same.
I suppose that you have the same rights for Edit buttons everywhere in your app. In this case you can extract autorization code into some custom tag (I recommend JSP tag files). For each edit button you will use your custom tag:
<customtags:hasEditPermission>
Edit button code goes here
<customtags:hasEditPermission>
All permissions will be declared once in your hasEditPermission.tag:
<%#tag description="Edit permission tag" pageEncoding="UTF-8"%>
<sec:authorize access="hasAnyRole('ADMIN')">
<jsp:doBody/>
</sec:authorize>
So in a case of new POWER_USER role you need to modify just one file:
<%#tag description="Edit permission tag" pageEncoding="UTF-8"%>
<sec:authorize access="hasAnyRole('ADMIN', 'POWER_USER')">
<jsp:doBody/>
</sec:authorize>
You can prepare and use tags for "Add new" and "Delete" buttons too. Hope this helps.
This is probably what you are looking for, with sample code
In your case, you would have BF_ADD_XXX, BF_EDIT_XXX and BF_DELETE_XXX etc.
This allows you to grant/revoke particular permissions (or BFs or business functions or whatever you want to call them) to/from particular roles.

How to auto refresh the page only one time?

I've a web page when a user logs in, it will have a link that shows the "username" and a link for "logout".
After the user logs out, the "username" and the "logout" links will change to "login" and "register" links, respectively.
The page uses javascript to check a user cookie, if the user cookie exists, it will show the "username" link and the link for "logout". If no user cookie exists, "login" and "register" links will replace the "username" and "logout" links.
Here's the problem: When a user who has log in, clicks the "logout" link, a perl script will delete the user cookie, and redirects back to the same page. The page does not show "login" and "register" links AUTOMATICALLY. Both links will appear ONLY after the user MANUALLY Refreshes the page.
It appears that I need a system to refresh the page automacally ONLY one time. How can this be done?
you could do it like this
after deconnexion redirect to 'page.html?1'
and in javascript side use this snippet
to check for the ?1 and redirect to 'page.html'
var refreshCheck= Number(window.location.search.slice(1));
if (refreshCheck == 1 ) {
window.location.href = window.location.substring(0, window.location.length-2);
}
I dont think it's good to force a refresh for this kind of things and you should consider the way you are dealing with the operation but if you want the easy way then you have to add this code which will refresh immediately
<meta http-equiv="refresh" content="0">

Grails Spring Security Core Plugin - adding flash message to login page

I am using the Grails Spring Security Core Plugin to secure a certain action using the following annotation.
#Secured(['IS_AUTHENTICATED_REMEMBERED'])
This causes the action to redirect to my login page if the user is not logged in. Once they are logged in they are then redirected to the original action.
How can I add a flash message to the login page in this scenario, i.e.
flash.message = "You must be logged in to submit a news story"
To clarify, I would only want the message to be displayed if the user was redirected to the login page after attempting to access this specific action. Other actions would not trigger the message.
I have solved this as follows.
Remote the annotation from the action.
Add the following code at the beginning of the action (news and submit being the relevant controller and action respectively).
if (!springSecurityService.isLoggedIn()) {
flash.message = "You must be logged in to submit a news story."
redirect(controller:"login", action: "auth", params:["spring-security-redirect" : "/news/submit"])
}
Add the following to the login form.
<input type='hidden' name='spring-security-redirect' value='${params['spring-security-redirect']}'/>
Add, for example, this to your login view:
<sec:noAccess url="/admin/listUsers">
You must be logged in to view the list of users.
</sec:noAccess>
See the security taglib's documentation.

Resources