Welcome Guest, Not a member yet? Register   Sign In
Use specific version of application after login
#1

[eluser]mvdg27[/eluser]
Hi guys,

I have a question about how to manage multiple versions of an application, based on a configuration value from the database that is only know after login.

My situation is like this: I have multiple versions of the same application (a CMS). Think: version 1, version 1.1, version 2 etc. All of them are maintained as a different application based on the same CodeIgniter base. They are all available through the same URL (mydomain.com/CMS).

Whenever a user visits this url, he's presented with a login screen. The login screen is the same for each user, and at this point it's not known which version of the CMS will be used.

After the login procedure, the version to be used is stored in a session, and based on this value I'd like to select the application (i.e. $application_folder in the index file). The reason for this is that I want to be able to upgrade the application on a per user base, instead of doing a serverwide upgrade. And simply changing a config item in the user database is the most time effective to do such a thing.

Now my problem off course is that I want to use CodeIgniter functionaly (from an application) before I know which application to use. Kind of a chicken and egg problem, and I've been struggling with it for a day now.

Anyone care to shed a new light on this? Any suggestions?

I hope I was clear enough with my explanation, if not I'd gladly explain further.

Thanks in advance for your input!

Michiel
#2

[eluser]dmorin[/eluser]
That kind of seems like a terrible idea that will cause you nothing but misery in the future. But, if someone wanted to pay me enough, here's what I would do. Obviously, you can't use any sort of CI functionality before you load CI. I would have the login system write a cookie that includes the version number to use. Then from the index.php file, you can read that cookie and set the application folder to the correct version. I would also do something to sign the cookie or hash it with a salt so someone can't just change it as the want.

But, if this is a CMS, that means unauthenticated users will also see these pages which means you can't rely on the login system writing this cookie. So what's you're plan there?
#3

[eluser]mvdg27[/eluser]
Dromin,

Thanks for your reply .. I think some extra explanation from my part is necessary to get a better idea of what the exact problem is.

The CMS is installed central on our webserver, and not in a public accessible location, whatsoever. What we do is use httpd aliases to load the scripts. This works for the website part as well as the administration part. As the CMS (website part and administration part) are further developed, we have multiple versions of the applications, and we want to be able to use multiple versions at the same time, to allow for gradual upgrades.

Our original way to handle this, is to pass the version number in an httpd alias. E.g.:

alias /cms /path/to/administration-application/versionx.x
alias /index.php /path/to/website-application/versionx.x

Now the idea is to move away from changing the httpd configuration for each upgrade and let the application handle this. For the website application this is a simple as checking for the correct version number to load for the requested page in the codeigniter index.php and according to that change the $application_folder. This works flawlessly.

For the administration part it's a bit more complicated, since the application version we want to use depends on the actual user logging in. Furthermore I want to use the same principle, having multiple working versions and be able to decide the exact moment an upgrade become available for a specific user. I don't really see misery in that, more benefits actually.

So the problem is really in separating the login part from the actual application and yet how to integrate it in the codeigniter index.php

On a further note, we use native sessions. So storing the application version in a cookie is not the way to go here, I think. Sessions should be a safe bet.

"But, if this is a CMS, that means unauthenticated users will also see these pages which means you can’t rely on the login system writing this cookie. So what’s you’re plan there?"

This remark doesn't really apply to our situation as we're talking about the administration part, not the website. And all codeigniter applications are not in a public location anyway.

Anyway, hope I have explained my problem a bit better. Thanks so far.

Michiel
#4

[eluser]dmorin[/eluser]
Quote:On a further note, we use native sessions. So storing the application version in a cookie is not the way to go here, I think. Sessions should be a safe bet.

When you say "native" sessions, do you mean php? If so then sure, that will work. Why is the administration portion not part of the application/CMS itself? Why do you have to handle it differently?

Quote:And all codeigniter applications are not in a public location anyway.
By public, i meant unauthenticated users, not the general public. You're original post made it sound as though deciding what version to use was based entirely on user logins so having to show a page to an unauthenticated user would seem to be an issue.
#5

[eluser]mvdg27[/eluser]
Quote:When you say “native” sessions, do you mean php? If so then sure, that will work.

Exactly. I use the native session library, which uses php sessions.

Quote:Why is the administration portion not part of the application/CMS itself? Why do you have to handle it differently?

Because in my opinion administering a website is fundamentally different from displaying it to visitors. In a simplified way of looking at it: the administration part is a fancy AJAX interface to the database. And the website part is a way of retrieving the data from the database and putting in a template. A person viewing the website has nothing to do with administering it. So the separation is a conscious design choice.

Quote:By public, i meant unauthenticated users, not the general public. You’re original post made it sound as though deciding what version to use was based entirely on user logins so having to show a page to an unauthenticated user would seem to be an issue.

Well, a login page is public by definition. So yes, an unauthenticated user can access this page. And after login the correct application should be selected. This exact process is the key of the problem.
#6

[eluser]dmorin[/eluser]
Ok, so I thought the big issue was storing the version between the login and using the application, but that seems to be solved with sessions. So what is the problem now?
#7

[eluser]mvdg27[/eluser]
Hehe .. we're getting somewhere now Smile

Consider this structure:

- index.php (codeigniter index)
- version1 (codeigniter application - $application_folder)
- version2 (codeigniter application - $application_folder)
- version3 (codeigniter application - $application_folder)

A person navigates to the CMS (mydomain.com/CMS) and the index.php is called. First thing happen is to check to see if the user is logged in or not (which is a typical CI-application task). But because the user is not logged in yet, it's not clear in which application (version) this should happen (by setting $application_folder to version1, version2 or version3). Only after the user has logged-in, we know which version to use, but then we're already in the CodeIgniter process. So the actual question is how to separate, yet integrate the login process.

Does this clarify the problem better?
#8

[eluser]nedloh312[/eluser]
I wrote a simple versioning script that works really well for me as i have lots of projects that go through different versions and this enables us the track release versions of applications easily.


Extract CodeIgniter Frame work into
C:\codeigniter\{VERSION}

Save the following code as loadConfig.php in C:\codeigniter\
Code:
<?php

if(( ! defined("APP_NAME")) OR ((defined("APP_NAME")) && trim(APP_NAME) == ""))
    exit('No "APP_NAME" definition found. Please set this');


$loadConfig = array();
/*
|--------------------------------------------------------------------------
| Current CI Version
|--------------------------------------------------------------------------
|
| Current CodeIgniter version.
|
*/

    $loadConfig['ciVersion'] = "1.7.2";

/*
|---------------------------------------------------------------
| PER-APP VERSION LOADER CONFIG
|---------------------------------------------------------------
|
| If an application is dependant on a specific version
| of CodeIngiter, set it here. When the system folder
| path is set, the version set here will be loader per app.
| You may also set the second array key to a version of the
| application to use.
|
*/

    $loadConfig['specificAppVersions'] = array (
        'CMS' => array(
            'fv'=>'1.7.2',
            'appv'=>'version_1'
        )
    );


$system_folder = $application_folder = "";

function loadCI() {
    global $system_folder, $application_folder;
    $system_folder = getSystemFolder();
    $application_folder = getApplicationFolder();
}

function getApplicationFolder() {
    global $loadConfig;
    $version = "";
    if(isset($loadConfig['specificAppVersions'][APP_NAME]['appv'])) {
        $version = $loadConfig['specificAppVersions'][APP_NAME]['appv'];
    }
    $path = "../" . APP_NAME . "/" .$version;
    echo $path;
    return $path;
}

function getSystemFolder() {
    global $loadConfig;
    $version = $loadConfig['ciVersion'];
    if(isset($loadConfig['specificAppVersions'][APP_NAME]['fv'])) {
        if(!is_dir(realpath("/CodeIgniter/" . $loadConfig['specificAppVersions'][APP_NAME]['fv']))) {
            exit('Unable to load core files');
        }
        if(!empty($loadConfig['specificAppVersions'][APP_NAME]['fv'])) {
            $version = $loadConfig['specificAppVersions'][APP_NAME]['fv'];
        }
    }
    $path = realpath("/CodeIgniter/" . $version);
    return $path;
}
loadCI();

And this is the new index.php for your application
Code:
<?php

define("APP_NAME", "CMS");
include('/CodeIgniter/loadConfig.php');
/*
|---------------------------------------------------------------
| PHP ERROR REPORTING LEVEL
|---------------------------------------------------------------
|
| By default CI runs with error reporting set to ALL.  For security
| reasons you are encouraged to change this when your site goes live.
| For more info visit:  http://www.php.net/error_reporting
|
*/
    error_reporting(E_ALL);

/*
|===============================================================
| END OF USER CONFIGURABLE SETTINGS
|===============================================================
*/


/*
|---------------------------------------------------------------
| DEFINE APPLICATION CONSTANTS
|---------------------------------------------------------------
|
| EXT        - The file extension.  Typically ".php"
| SELF        - The name of THIS file (typically "index.php")
| FCPATH    - The full server path to THIS file
| BASEPATH    - The full server path to the "system" folder
| APPPATH    - The full server path to the "application" folder
|
*/
define('EXT', '.php');
define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
define('FCPATH', str_replace(SELF, '', __FILE__));

define('BASEPATH', $system_folder.'/');

if (is_dir($application_folder))
{
    define('APPPATH', realpath($application_folder) . '/');
}
else
{
    if ($application_folder == '')
    {
        $application_folder = 'application';
    }

    define('APPPATH', realpath(BASEPATH.$application_folder) . '/');
}
/*
|---------------------------------------------------------------
| LOAD THE FRONT CONTROLLER
|---------------------------------------------------------------
|
| And away we go...
|
*/
require_once BASEPATH.'codeigniter/CodeIgniter'.EXT;

/* End of file index.php */
/* Location: ./index.php */

Pretty self explanitory, pretty hacky aswell but don't care. If it has to be super perfect (For a client, not internal use like this one) then you might want to use a hook.

Dave
#9

[eluser]dmorin[/eluser]
If the version has to be user dependent (instead of alias/virtualhost) and you don't know the user until they're logged in, then the login system has to be separate from the rest of the versioned application.

You could do this one of two ways. First woud be to have the login system be a totally separate CI app that can be updated/modified as necessary. The other option would be to always use the authentication system of the newest version.

So the work flow would be something like this:

1. In index.php, check for an existing login session.
2. If a session exists, get the version, set the app path and continue loading
3. If the session doesn't exist, set the app path to the login application (or the latest application)
4. If needed, you could also re-write the server vars like PATH_INFO to set the requested url to the login page.

Then, when they login successfully, the system will write the session and include the version id. When the page reloads, the index.php page will notice the new session and direct them to the appropriate version.
#10

[eluser]mvdg27[/eluser]
Hey .. that's actually a good idea. Simply keep the login procedure inside the application, and use the authentication of the newest version! I hadn't thought of that approach yet. I think that could solve the problem.

Took a bit to define the exact problem, but in the end we got there .. gonna give it a go.

Thanks a lot! -Michiel




Theme © iAndrew 2016 - Forum software by © MyBB