Welcome Guest, Not a member yet? Register   Sign In
Restrict access to profile editing?
#1

[eluser]Braden Schaeffer[/eluser]
As a learning experience project, I am working on a basic store that allows a user to purchase a theme file and have access to it online.

Here's the gist... let's say I have 10 users and and 2 themes (Theme A and Theme B). 5 users bought access to Theme A and 5 bought access to Theme B. You would edit the files and http://site.com/users/username/edit/theme/theme_id. Though it's not exactly profile editing, you can see how it's similar.

To be honest, outside of logging people in, I have no idea how to prevent anyone from going directly to the URL above and having access to a the users theme file.

I think I have a themes_purchased table in mind where I store a purchaser_id corresponding to a user_id in a users table, so at least I will be able to tell whether the specific user has access to a theme or not, but restricting access to themes purchased by a specific user from other users is a different story completely (at least to me).

Am I on the right track. Does the URL organization above make it at least possible to do what I am thinking of doing?

Any suggestions would be greatly appreciated!!!

Thanks in advance, Braden
#2

[eluser]bigtony[/eluser]
Rather than http://site.com/users/username/edit/theme/theme_id I would separate the login from the edit.

So you would have pages like this:
http://site.com/login and http://site.com/edit/theme_id

Your Edit controller would need to check that the user is logged in and that the passed in theme_id is allowed for that user (and if not either display an error message or redirect to the login page).

If you want example code, just ask.
#3

[eluser]Braden Schaeffer[/eluser]
[quote author="bigtony" date="1250863143"]Rather than http://site.com/users/username/edit/theme/theme_id I would separate the login from the edit.

So you would have pages like this:http://site.com/login and http://site.com/edit/theme_id[/quote]

Thanks for the reply!

After I thought about it, I came up with the same URL scheme.

So far, here's how I am verifying access using session data:

If the user is logged in, I store logged_in = 1 in the session. (I never uses this simply as the verification, but only use it to decide whether or not I need to display a login form and other things on certain pages).

I also store the username in the session data.

Then, I create a checksum that is an md5 hash of a predefined salt plus the loggedin variable plus the username and store it in the session.

After that, when they visit a restricted page, I run a code that verifies that the session checksum data equals the returned test checksum I get from an access helper... if that makes any sense. Here's an example:

Restricted page:
Code:
<?php

class Edit extends Controller {

    function __construct()
    {
        parent::Controller();
    }
    
    function index()
    {
        //Stored session data
        $loggedin = $this->session->userdata('logged_in');
        $checksum = $this->session->userdata('checksum');
        
        if($loggedin == 1 && isset($checksum))
        {
            $this->load->helper('access'); //custom helper, see code below
            $username = $this->session->userdata('username');
            
            //$result will be TRUE or FALSE depending on if the session checksum
            //is equal to the test_checksum created with the same information
            $result = access_verify($checksum, $loggedin, $username);
        }
        else
        {
            $this->load->view('noaccess');
            return;
        }
        
        if($result)
        {
            //if the function 'access_verify' returns TRUE
            //allow the user access and display content
        }
        else
        {
            //if the function 'access_verify' returns FALSE
            //deny the user access and display a 'no access' message
        }
            
    }

}

My access_helper.php file:
Code:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');


if ( ! function_exists('access_salt'))
{
    function access_salt()
    {
        //my predifined, static salt string
        $salt = "myrandomstringhere";
        return $salt;
    }
    
}

//This runs the same code that created the user checksum at login,
//but gets it's data from the user session data (see above code)
if ( ! function_exists('access_verify'))
{
    function access_verify($checksum = '', $loggedin = '', $username = '')
    {    
        if($checksum == '' || $loggedin != 1 || $username == '') return FALSE;
        
        $salt = md5(access_salt());
        $username = md5($username);
            
        $test = md5($salt.$loggedin.$username);
        
        if($test == $checksum)
        {    
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
}

In my view (and please note I'm really, really, really new at this), the above two examples seem to be working out alright. My question is whether or not this is necessary, or whether I am doing to little or what? Does this look good or are there some alarms here?

[quote author="bigtony" date="1250863143"]If you want example code, just ask.[/quote]

If any of the code above looks like a bad idea... I'd love to see an example. Verifying access is something completely new to me.

@bigtony Thanks again for the reply! -Braden
#4

[eluser]bigtony[/eluser]
Braden - the principle of how you are approaching it is perfectly sound. You may want to consider the following points if you haven't already:

(a) You could refactor the code that reads and checks the session variables (in your index() function) to a helper function so as not to have to duplicate in all your controllers.

(b) Be careful if some of your controllers have other access points (apart from index()) that would also require the authority check. (Consider using the _remap() function).

© You can encrpyt session data via CI which would have a similar effect to your salting & md5'ing.

(d) You can also use database sessions which will give additional security compared to the default.
#5

[eluser]Braden Schaeffer[/eluser]
Thanks for all your help. I'm glad to know I am doing something right.

[quote author="bigtony" date="1250942313"](b) Be careful if some of your controllers have other access points (apart from index()) that would also require the authority check. (Consider using the _remap() function).[/quote]

I have looked into the _remap function a little bit, but I am not sure how calling my validate function at each access point is not the same thing. Is that a security issue?
#6

[eluser]bigtony[/eluser]
[quote author="Braden Schaeffer" date="1251155965"]I have looked into the _remap function a little bit, but I am not sure how calling my validate function at each access point is not the same thing. Is that a security issue?[/quote]
It's fine to call it at each access point. The only issue is it can be easy to forget, especially if you add new functions to the controller later on. _remap just lets you route all calls through one function, where you can dispatch as appropriate. No need to change the way you are doing it though.




Theme © iAndrew 2016 - Forum software by © MyBB