Override login from package

Permalink
Anybody tried this? I've got it to remove the core login and install one on install of package but its only loading the view for login and not my custom controller I know you can do this in the Top level directory but from a package?

DavidMIRV
 
ijessup replied on at Permalink Reply
ijessup
I'm trying to do this as well. I've successfully written a script that uses an LDAP host for user authentication, but I don't like to hardcode scripts into c5's system files.

From the package installer, I tried deleting the login page and installing the new one, but that borked the login page competely.

I'll report my findings as I progress.
ijessup replied on at Permalink Reply
ijessup
public function install() {
   $pkg = parent::install();
   Page::getByPath('/login')->delete();
   Loader::model('single_page');
   $new = SinglePage::add('/login', $pkg);
}
public function uninstall() {
   $pkg = parent::uninstall();
   Loader::model('single_page');
   $old = SinglePage::add('/login');
}
will get c5 to look at the login.php file in the package's 'single_pages' folder, but c5 ignores the login.php file in the package's 'controllers' folder.
ijessup replied on at Permalink Reply
ijessup
It looks like this is an issue in '~/concrete/libraries/loader.php' @line 413-444.

Any file in the root directory will override a core c5 file, but a core c5 file will always override a packaged file.
andrew replied on at Permalink Reply
andrew
Ah, I see what you mean. We can fix this. Generally it should go local directory, then packages directory, then core directory.

Try replacing this:
if ($path != '') {
            if (file_exists(DIR_FILES_CONTROLLERS . $controllerFile)) {
               require_once(DIR_FILES_CONTROLLERS . $controllerFile);
               $include = true;
            } else if (file_exists(DIR_FILES_CONTROLLERS . $path . '/' . FILENAME_COLLECTION_CONTROLLER)) {
               require_once(DIR_FILES_CONTROLLERS . $path . '/' . FILENAME_COLLECTION_CONTROLLER);
               $include = true;
            } else if (file_exists(DIR_FILES_CONTROLLERS_REQUIRED . $controllerFile)) {
               require_once(DIR_FILES_CONTROLLERS_REQUIRED . $controllerFile);
               $include = true;
            } else if (file_exists(DIR_FILES_CONTROLLERS_REQUIRED . $path . '/' . FILENAME_COLLECTION_CONTROLLER)) {
               require_once(DIR_FILES_CONTROLLERS_REQUIRED . $path . '/' . FILENAME_COLLECTION_CONTROLLER);
               $include = true;
            } else if (is_object($item)) {
               if ($item->getPackageID() > 0 && (file_exists(DIR_FILES_CONTROLLERS . $controllerFile))) {


With this (warning, I dashed this off pretty quick):

if ($path != '') {
            if (file_exists(DIR_FILES_CONTROLLERS . $controllerFile)) {
               require_once(DIR_FILES_CONTROLLERS . $controllerFile);
               $include = true;
            } else if (file_exists(DIR_FILES_CONTROLLERS . $path . '/' . FILENAME_COLLECTION_CONTROLLER)) {
               require_once(DIR_FILES_CONTROLLERS . $path . '/' . FILENAME_COLLECTION_CONTROLLER);
               $include = true;
            } else if (is_object($item)) {
               if ($item->getPackageID() > 0 && (file_exists(DIR_FILES_CONTROLLERS . $controllerFile))) {
                  require_once(DIR_FILES_CONTROLLERS . $controllerFile);
                  $include = true;
               } else if ($item->getPackageID() > 0 && (file_exists(DIR_PACKAGES . '/' . $item->getPackageHandle() . '/' . DIRNAME_CONTROLLERS . $controllerFile))) {
                  require_once(DIR_PACKAGES . '/' . $item->getPackageHandle() . '/' . DIRNAME_CONTROLLERS . $controllerFile);
                  $include = true;
               } else if ($item->getPackageID() > 0 && (file_exists(DIR_PACKAGES . '/' . $item->getPackageHandle() . '/' . DIRNAME_CONTROLLERS . $path . '/'. FILENAME_COLLECTION_CONTROLLER))) {
andrew replied on at Permalink Reply
andrew
Unfortunately there's no graceful way to do this. You could create an alternate sign-in script on your package and then link to it instead.

In the future we're going to try and make our login procedures more flexible to allow third party authenticators to extend the login page without having to remove it entirely. The login page won't be hard-coded to access concrete5 login and openid. Instead it'll have concrete5 login + any number of other login providers (which can be installed via package) like twitter, facebook, openid, etc...
ijessup replied on at Permalink Reply
ijessup
Thanks for chiming in!

As it stands, my "work-around" deletes the existing Login page and adds a new one which just tells the controller to redirect to the new login page.

You're right, though. Not graceful, but for the most part seamless, at least for the end user experience.

Can't wait to see support for third party authentication. I should be able to port my existing LDAP authenticator fairly easily. Thanks to Zend, it was pretty easy to write out and easy to build in redundancy should the Active Directory go missing.

Any chance we'll be seeing a v5.4.2 soon?

Thanks again!
jaredquinn replied on at Permalink Reply
jaredquinn
Andrew,

I already have a fairly stable package that implements a nice modular login which currently supports both Facebook and Twitter logins.


It allows either type of account to be linked to an existing account or creates a new account.

Let me know if you'd like to take a look and I'll PM you details. I plan on releasing it on the Marketplace after a little more testing.
Fernandos replied on at Permalink Reply
Fernandos
Thanks a lot for this Andrew, can't wait to see that happen!
It's been quite about this.
5fly replied on at Permalink Best Answer Reply
5fly
Way too late... but I had the same problem and just added the following into my package controller to associate the single packages with my new package:

$cID = Page::getByPath('/login')->getCollectionID();
$db->execute('update Pages set pkgID = ? where cID = ?', array($pkg->pkgID, $cID));
jordanlev replied on at Permalink Reply
jordanlev
Very clever! I'd also put some code in the package controller's uninstall() method to reverse that operation (before the call to parent::uninstall() ) -- setting pkgID back to null on that page -- otherwise the login page will get deleted when you uninstall the package.

-Jordan
5fly replied on at Permalink Reply
5fly
Good spot! :) Ill add that in now before I forget.