I am building an app, in my app i am want to have a page for an admin to manage user menu permissions. What this means is that supposing i have the following menus:
Products
-Add
-Edit
-View
-Delete
And
Users
-Add
-Edit
-View
-Delete
Now i want User A to be only able to see and go to:
Products:
-View
And
Users:
-View
The rest of the menu items will be invisible and inaccessible to User A.
What i have set out to do is to create tables for this in my database:
menu_groups
-id
-name
-description
menu_items
-id
-menu_group_id
-name
-state
-description
Menu groups table will hold all top-level menu items, in this case: products and users.
Menu items table will hold sub menu items: eg. Add, Edit, View, Delete
Now when the app loads i plan on checking user permissions then loading these menu items from the database, displaying and then caching them. Obviously i will put a filter/middleware or whatever it's called on those routes on the server so no one can bypass it.
My question now is, is this the right way of doing it? In terms of security, efficiency etc. Or is there another simple way of achieving this?
I use mysql for my database, laravel-5 on my server and angularjs for client side.
I did something similar with my application, it's a good solution. When a user tries to access a forbidden section on my website, laravel returns a 401 error which I catch automatically in my angular application by an interceptor.
$httpProvider.interceptors.push(function() {
return {
'responseError': function(rejection) {
if(rejection.status === 401) {
//Redirect to login, show error etc.
}
};
});
Related
I'm building an eCommerce website using D7, mainly with Commerce and DS. To get a better perfomance I installed Display Cache which is a module that caches the rendered HTML of an entity for anonymous and authenticated users. In my particular case i'm caching the Product Display (a node which references a product and it's variations if any).
After a few hours of configuration I end up with a "good result" in performance. All my entities where cached by rol, in teaser and full mode... but then the problem arises when the user clicks "Add to cart" button because it's not adding products to the cart... nor it is showing an error.
One possible reason is the form token or some form processing function that is invalidating the action because the form is not generating everytime as expected. I read how to disable the form token in the "Add to cart form" (or any form) but it's not working. I set $form['#token'] to false, but still is not adding products to the cart.
Probably the solution is not easy, but I need clues of what I could do or where I could start tackling the problem.
So, thanks for you expertice.
A solution to this combination of modules, in order to have cached display for anonymous & authenticated users and add to cart forms is to disable cache programatically of the requested product in all it's displays... and disable the token of the "add to cart form".
Here is the code for disabling the token:
function YOUR_MODULE_form_alter(&$form, &$form_state, $form_id) {
if (strstr($form_id, 'commerce_cart_add_to_cart_form') || strstr($form_id, 'views_form_commerce_cart_form_default')) {
unset($form['#token']);
}
}
And here is the code to remove caching when a an add to cart button is pressed:
function YOUR_MODULE_init() {
if (isset($_POST['product_id'])) {
$id_product = intval($_POST['product_id']);
$res = views_get_view_result('sys_search_product_display', 'default', $id_product);
foreach ($res as $nid) {
display_cache_flush_cache('node', $nid);
}
}
}
Note that "sys_search_product_display" is just a view which receives the ID of the product and returns the ID of the product display. This can be done in other ways.
What is the best way to get the Sentry Groups my USER model belongs to in Laravel 4.1?
I couldn't find anything in the docs about this.
The Sentry docs are pretty bare bones. You can do this to get the groups belonging to a user:
$user = User::findOrFail($id);
$user->getGroups();
foreach($user->groups as $group)
{
echo $group->name;
}
According to the sentry docs perform the getGroups() Method on the user.
I have a website where all the pages are accessible to the public except for one Releases page which is user specific or maybe to a specific group .I have a seperate login page to gain access to 'Releases' page based on authentication.How do I go about this?Using Acl or Authorize function?I am very confused..Also do i need to use the same users table for authenticating this page, in that case do I use this User login page as an elemnt in my other login page.Could somebody please hint me on how to proceed?
ACL is overkill for many situations.
What I normally do is something like this in my controller:
public function releases() {
$this->_allowedGroups(array(1,2,3));
// rest of code here
}
Then in my app controller:
public function _allowedGroups($groups=array()) {
if( !in_array($this->Auth->user('group_id'), $groups) ) {
$this->redirect(array('controller'=>'users', 'action'=>'login'));
}
}
Acl should do your work.
And is there any specific need that you are using a separate login page??
A single login page and and a single users table should suffice your needs if you implement acl. Only those users who have rights to view the Requests page will be allowed to do so.
you may do something like this..
on core.php, put
Configure::write('Routing.prefixes', array('release'));
and do the verification on the AppController:
class AppController extends Controller{
public function beforeFilter(){
if (isset($this->params['prefix']) and $this->params['prefix'] == 'release'){
if ($this->Session->read("User.type") != 'admin'){
//redirect the user or throw an error...
}
}
}
}
so, youdomain.com/release/* will only be accesible by your administrators...
also, i don't see why you need two logins pages... you could just put a flag on your users table saying if the user is or not an admin... and on the login, set the User.type property on session.
if you don't need of complex permissions control, i think you don't need use ACL.
i'm looking for an easy way to export all active directory users info into unique vcards for each. there is some info i'd like to leave out of the vcard like home phone, and emergency contact. i've looked around the web and have little luck finding anything. any help would be appreciated.
I doubt there will be a very easy way. Ultimately, you need to
enumerate all your users (or a subset therefore)
iterate over the resulting list of users
export each user's data to a VCard
For the searching & iterating part, you can use a PrincipalSearcher to do your searching:
// create your domain context
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
{
// define a "query-by-example" principal - here, we search for a UserPrincipal
// this "QBE" user would give you the ability to further limit what you get back
// as results from the searcher
UserPrincipal qbeUser = new UserPrincipal(ctx);
// create your principal searcher passing in the QBE principal
PrincipalSearcher srch = new PrincipalSearcher(qbeUser);
// find all matches
foreach(var found in srch.FindAll())
{
UserPrincipal foundUser = found as UserPrincipal;
if(foundUser != null)
{
ExportToVCard(foundUser);
}
}
}
And now all that's left to do is create the ExportToVCard function :-) See e.g. this blog post with code samples and further links for help.
If you haven't already - absolutely read the MSDN article Managing Directory Security Principals in the .NET Framework 3.5 which shows nicely how to make the best use of the new features in System.DirectoryServices.AccountManagement. Or see the MSDN documentation on the System.DirectoryServices.AccountManagement namespace.
If you just want the data itself, I would take a look at Softerra's free LDAP Browser, found here.
Setup a profile for your directory server - once it's connected in the browser, you'll see the default schema for the BaseDN you've provided during the initial setup. On the server icon, right click, and hit "Export Data".
The export wizard will walk you through most of the process, but the important part is Step 3. If you want to find all users, just set your search filter to (objectClass=user), make sure your search scope is SubTree, and then then edit what attributes you want to return.
You'll have to process the results into VCards, but this is the easiest\fastest way of getting all the users and attributes that you want.
I have setup a CRUD area on my frontendAPI.php file (testing my models)... and I even managed to secure it. I would like to do this the proper way... I would like to establish a separate directory/ Page for the Admins. Please advise on this.
Still new at this but I'm trying to do the same for a news page, think i've got the login part working but having problems with the CRUD (will post a question on it shortly) - i have a table to populate with data from an rss feed (but will be manually populated with a CRUD to start with) and then have a page on the front end to pull out the details using views to format each news story.
Create a new directory called /page/Admin
Create a new file here based on the function e.g. news.php containing
class page_admin_news extends Page {
function init(){
parent::init();
$p=$this;
$crud=$p->add('CRUD');
$g=$crud->setModel('News');
if($crud->grid)
$crud->grid->addPaginator(30);
}
}
In Frontend.php, you need to enable the login - for an admin only access, the BasicAuth may be sufficient but there are also classes to use a database to obtain username and password infromation e.g. for a membership site - heres the basic one.
// If you wish to restrict access to your pages, use BasicAuth class
$auth=$this->add('BasicAuth')
->allow('demo','demo')
;
You need to modify Frontend.php to enable pages that can be viewed
without being logged in
$auth->allowPage('index');
$auth->allowPage('news');
$auth->allowPage('links');
$auth->allowPage('About');
if (!$auth->isPageAllowed($this->api->page))
{
$auth->check();
}
And also in Frontend.php, you need to create a different menu if logged in. Note the login and logout pages dont actually exist.
if ($auth->isLoggedIn())
{
$this->add('Menu',null,'Menu')
->addMenuitem('News','admin_news')
->addMenuitem('logout')
;
} else {
$this->add('Menu',null,'Menu')
->addMenuitem('News','news')
->addMenuitem('Links','links')
->addMenuItem('About')
->addMenuItem('Login')
;
}
When you login, it goes to page/index.php by default so if you want it to redirect to a particular page when you log in so you can add this to page/index.php
class page_index extends Page {
function init(){
parent::init();
$p=$this;
if($this->api->auth->isLoggedIn())
$this->api->redirect('admin_news');
Hope that helps.
Trev