Should placeholders be modified from Controllers? - php

Let's say I have a simple website where users can log in. When they are logged in, I want to show them a different message than users who are not (guests). This message should render in a placeholder, by appending the message to it.
Where should this be done? I was thinking of having my controller check whether the user is logged in or not, and then append to the placeholder via $this->view->placeholder("sidebar")->append()

Why not just put it in the layout itself?
For example, I often have the following situation that affect my layout: if the user is logged in, I want to display his username, a link to view/edit his profile, and a link to logout. If he is not logged in, then I show him a link to login and a link to register.
The code to handle all this uses Zend_Auth::hasIdentity(), Zend_Auth::getIdentity(), and the url() view-helper. To keep the layout code a little leaner, I often push all this into my own view-helper called something like authLinks().

A better solution might be to switch the layout based on the authentication status of the current user. This could be done with a plugin in preDispatch, or in the preDispatch within your controller. By placing the display logic in the view layer, you don't have to update lower level code if you decide to change the message, or remove it all together.
I would personally opt for it being in a controller plugin since it abstracts the concern of checking authentication status and updating the view away from controllers, and prevents you from having to worry about putting the appropriate code in any controllers you create in the future.

That is a matter of personal preference. I always delegate that responsibility to the view, so in my mind yes it should be handled by the view.

Related

User permission and software security

I am developing an application in php codeigniter. Now I am worrried abt the permission.
I need page wise permission, page may be add records page, edit page, delete page and print report etc. There will be many users as well, and applicaiton will grow with passage of time.
If I implement ACL that will better for me or not
what can be ideal for me any suggestion.
First, let's clear up some terms: I personally use the security term for things like preventing SQL injection, XSS attacks, where we have to validate input, filter/sanitize values, take care of the dynamically generated SQL commands, take care of properly escaping output (for JSON or HTML text or HTML attributes), etc. This is not about what you are asking, if I understood well.
The access control or permissions system is where you give or deny access to a function for a user. It can be secure or not. I understand that to deny a user which does not have permission the access to a function may sound like "security", but I wouldn't use this specific word in this context, to avoid confusion.
Now, the answer:
I strongly recommend you create a few base controller classes to your needs. Read the following blog post carefully (it is short and useful): http://philsturgeon.co.uk/blog/2010/02/CodeIgniter-base-Classes-Keeping-it-DRY
A code to check if the user is properly authenticated (logged in) is essential. If the user is not logged in, redirect to home page or login page.
For fine-grained control, you could create your ACL in the database using the users table, plus an actions table, plus an acl table...
The users table would contain the users data (id, name, login, password, etc)
The actions table would contain the id field and at least one more field containing what suits best for your application: it can be only the controller class name (the first part of the URL, for example: "products"), granting access to the whole "products" controller or not. Or you may want to include both the controller class AND the method name (the first and second parts of the URL, for example: "products/add" and "products/delete"), and so on.
To decide about the actions table is the most decisive step. Think very well about it, balance your needs (your "true" needs)... I developed a system where each and every action has its entry. It is good, but it needs work to be maintained.
A very useful column for the actions table is a human-readable description of the action.
The acl then would be nothing more than a column for the user id and another column for the action id.
A "master" grant/deny access field in the users table is useful too, in case you want to temporarily deny access from a specific user, without having to delete all his permissions and maybe having to restore it later.
With the database tables and your "controller/method" or "actions" strategy well defined, you can easily code in your base controller class a function which checks if the user have permission to execute the requested action.
This is the basic. In my system, I have the users administration interface, where I can grant/deny the actions for each user (I use an ExtJS tree with checkboxes). One of these actions is the own user management. I have gone one step further, where the user who can access the user management may "delegate" (grant/deny) to other users only the actions he himself has access to.
The system has several modules, and functions. The interface does not show anything the user does not have access. So, I have users who can see only a single or a couple of modules, and they don't even imagine the existence of the other modules.
It requires more work to manage all this, but the result worths.
I also log each granted access, so it is possible to track who did what, and when. This log feature is very very easy to add, since you have this base controller "master function" allowing or disallowing the users to perform the actions.
I hope I have helped. I've just shared a bit of what worked (and works) for me...

How do I put CodeIgniter's/TankAuth's register and login forms on the same page?

I'm using CodeIgniter for my php framework and TankAuth for my authorization/registration. By default, TankAuth places the registration and login forms on separate pages. I would like to place the log-in form in the navigation bar that occurs on every page. There is also a sign-up page that will have the registration form occurring simultaneously as the log-in form (located in the navbar).
I am currently using this in controllers/signup.php .index()...
$this -> load -> view('templates/header');
$this -> login();
$this -> register();
$this -> load -> view('templates/footer');
This displays correctly but I have two issues:
1 Will I have to redefine TankAuth's methods in every controller that will have the log-in form?
2 When I try to register it tells me that the log-in form should be filled out as well. That's obviously a catch-22.
(I apologize if this is too domain specific or vague; I hope it makes sense to those who have worked with the framework.)
I'm not sure what you are trying to achieve by just combining login & register views, they were not designed to work together, so you definetly need to do some modifications to the base tank auth structure.
This really shouldn't be a confusing issue as its just a problem you created for yourself by combining two very similar forms.
To simply walk through this, (and I don't know what code changes if any you made) first you must create your own login (html), set the form action="/auth/login".
The login will submit, IF it is all clear the user is logged in and you handle it like that, HOWEVER if they fail to login, they will be brought to a single page login (default/or modified) where they can re-try again.
The same should follow for registration, set the form action="/auth/register" and let it submit against tank auth controller. Again, if registration is successfull, they will just get shuttled through wherever, otherwise brought to a single registration page.
Use the original login and registration views as a start to what you need to change / update.
Tank Auth is really a plugin, that you need to modify to suit your needs, its code is clean and clear, so just go through it so you understand what happens at login, what happens at registration, activation etc, otherwise mashing things together will not get you anywhere. In my personal experience with the library, I have ALWAYS modified it beyond the initial setup, just because it is simple to do.
I'm not sure if this is still an issue but if you really want to do that, you can include one view in another as an IFRAME without any issues.

PHP Web Application Design Basics

I am making a twitter application using PHP. Please excuse me if this question is elementary. In my application, the initial landing page (index.php) contains code for login/oauth. If the user logs in successfully, should I load a new page altogether or simply echo html that renders the user's profile page. For example:
if(login success)
{
load a file that renders selected user's profile page
}
or something like
if(login success)
{
echo html that renders a profile page.
}
If I understand correctly, you're trying to decide what to show the user once they log in. Rather than think what you should show them, what does the user want to do right away? Why do they use your site? If users want to see their profile right off the bat, then do that. If they want to see feed activity, show them that. To start off, you may want to create a simple page that acknowledges they are logged in and give them their major options. Track what users click and see what that tells you. If the vast majority use feature X immediately, then consider loading feature X first. If the users are all over the map, let them pick what they want to do, record it as a preference in their profile, and load that automatically.
In the end, the best thing to show a user when the log in is the first thing they most want to see. :)
I'd recommend looking into the use of some sort of PHP MVC framework.

Best way to track the stages of a form across different controllers - $_GET or routing

I am in a bit of a dilemma about how best to handle the following situation. I have a long registration process on a site, where there are around 10 form sections to fill in. Some of these forms relate specifically to the user and their own personal data, while most of them relate to the user's pets - my current set up handles user specific forms in a User_Controller (e.g via methods like user/profile, user/household etc), and similarly the pet related forms are handled in a Pet_Controller (e.g pet/health). Whether or not all of these methods should be combined into a single Registration_Controller, I'm not sure - I'm open to any advice on that.
Anyway, my main issue is that I want to generate a progress bar which shows how far along in the registration process each user is. As the urls in each form section can potentially be mapping to different controllers, I'm trying to find a clean way to extract which stage a person is at in the overall process. I could just use the query string to pass a stage parameter with each request, e.g user/profile?stage=1. Another way to do it potentially is to use routing - e.g the urls for each section of the form could be set up to be registration/stage/1, registration/stage/2 - then i could just map these urls to the appropriate controller/method behind the scenes.
If this makes any sense at all, does anyone have any advice for me?
I think creating a SignupController is a fine idea. The initial user registration is a distinct process, and ought to be separate from general profile management tasks.
If you've been a good developer and keeping your controllers thin and your models fat, you ought to be able to avoid any code duplication. If you find yourself duplicating, it's probably a good idea to think about refactoring.
As a concrete example, consider your user's email address. Let's say you're pretty strict, and any time a user changes their email address, they have to do a little confirmation-email dance. During signup, you'll want the user to return to the signup process after they click their confirmation link. When an existing user is changing their email address, you'll want them to land somewhere else (like their profile). It's likely that you'll want different content in the body of the confirmation email is each case. Trying to make /user/profile handle both cases is going to start creating a bunch of complexity where the action needs to figure out context and behave accordingly.
The better solution is to decide that signup is it's own mode of interaction, distinct from general profile management. Therefore, it gets its own controller, which shares model and view resources with other controllers.
That's my take, anyway.

how can I bust out of a PHP class initialization if the user isn't logged in?

I'm writing an admin section to a site using CodeIgniter. I am writing an Admin class that extends the Controller class, and then controllers for admin pages will extend Admin. I do this because I want the Admin class to check the user's session to make sure he is logged in -- and if not, to show the login page and abort initialization of the class.
To me, that seems like a nice abstraction -- not worrying about the user being logged in for any of the administration pages and functions, just writing them and letting the super class worry about it. But how should I do this?
If I throw an exception from the Admin constructor, will that stop the sub class extending it from being created? is there a better way to do this? #anyone who has used MVC before, have you dealt with something like this before?
show_error() words similarly to die() in native PHP. It will immediately halt execution and display the error string, no matter where it's called: a view, a model, or (more commonly) a controller. Keep in mind though that any state manipulation that occurs up to the call won't be reversed.
As for best practice to perform rights checking, other folks here have and will recommend other solutions, but I can give you the approach I usually take.
If the admin is going to be just another non-comp savvy end user in a site with multiple non-admin users, I would just create a flag in the users database table, and the user's row is loaded in a custom controller MY_Controller. Then, I'd just attach a check on each function in a controller class if different functions have different rights restrictions. If they all have the same rights restrictions, I'd put it in the controller, as #Lukman suggests.
If the admin is going to be completely separate from the user experience, you might consider creating an admin subdomain and installing CI on it. That way you don't have to worry about anything other than setting up a global custom controller that manages rights.
In your case, the approach I'd take is a bit different. I'd create a custom controller and extend EVERY controller on the site from it (this is just good practice in my opinion since there almost always winds up stuff that is best done in one place). In that controller, I would run:
if(strcasecmp($this->uri->segment(1) , 'admin') === 0)
if($this->session->userdata('admin') !== 1)
show_error('Access Prohibited');
In the constructor of your Admin class, check if the user is logged in and redirect to the login page if not.
public function __construct() {
// assuming you have your user authentication handled by UserLogin class
if (!UserLogin::is_logged_in()) {
redirect("/uri/to/login/page");
die;
}
// do normal stuff
parent::__construct();
}
I would suggest that you apply the "is a" test here. "Is a(n)" admin a controller? I would say no. Rather, a controller providing access to administrative pages might have the property of "requires admin authentication". Therefore, it seems like you should use a decorator on the controller class to do access control. For the admin sections you can set an "Admin access controller" and for non-admin sections you can set it to null or a base class that has a default action of doing nothing.
Your way probably will work fine, I'm just kind of approaching it more from the "how should the design look" kind of angle.

Categories