I have a Drupal Web Site on an online server. Authenticate users can create and edit articles (nodes), and anonymous users can view them. When the server is down for any reason (like a power failure), the URL is redirected to a Backup Server that contains a Copy of the real server. This copy allow all users to View the actual content of the Web Site.

Of course, if a user manage to log in the Backup Server and decide to Create or Edit an article, his modifications will be override during the next copy of the real server to the Backup Server (next sync).

The most easy way to avoid that potential issue is to disable the login on the backup server. I did a search on Internet but the only solution I can find is to hide the login block, which do NOT solve the problem.

One potential issue:
If an authenticated user is viewing an article when the failure occur, than decide to click on the Edit tab, the user will be redirect to the login page (the user is not on the same server so he do not have any active session on that server). Apache Mod Rewrite can not help because the URL is the same as the real page, the URL is not the Login URL.
Example:
Page to edit an article: http://www.example.com/node/171/edit
Login page displayed when trying to edit the same article on the backup server: http://www.example.com/node/171/edit (exactly the same URL)

I want to completely disable the login feature, in the way that will make the Login page impossible to access.

Is it possible to do that?

Thanks

CommentFileSizeAuthor
#12 loginbyrole.jpg230.3 KBjimboh

Comments

j2r’s picture

when you are taking back up you are probably moving the DB not the file?
if this is the scenario you can make changes in page.tpl.php and in init() function to not allowed user to go to some specific page.

gaellafond’s picture

Thanks for your suggestion, I will have a look at this soon.
Is it possible to block the login page as well as all add and edit pages?

[edit]
When I take the backup, I do a DB backup that I copy across to the other server than I restore that DB backup on the backup server. I don't copy the MySQL DB files itself. It's too risky, the DB may have pending transaction while you are copying them.

j2r’s picture

One simple solution is too destroy the session in init() function so that user will automatically became anonymous and user can not go to add and edit pages
(This may be not the best solution but it will work)

denes.szabo’s picture

Go to the site admin/user/rules

Create one rule, allow access to the admin ("admin" for example) and create an other rule "not allowed" for % (everyone).

If you want to allow the login again, delete the % rule.

I have just tested it, works.

gaellafond’s picture

@Denes
Thanks, that sound promising. But, unfortunately, I don't think we can use that solution. The idea of this feature is to allow users to be able to log on the Web Site when the live server is running, and not be able to log when the Backup server is running. The Backup server automatically takes effect when the live server is down. This ensure our Web site is always up and running. The backup process works only one way to make it simple, so, if an editor change something on the Backup server, its modifications will be wipe out when the live server become up again.

The backup process also backup the database. Modifying a file is a viable solution since I can exclude that file from the backup process. It will be problematic if that file get change due to an update, but I can live with this. A modification in the database is not possible since I can not exclude only one DB row from the backup process.

Thanks anyway, any solutions are welcome. I will see what suit me best when I will have to work on this project again.

fotuzlab’s picture

Not a techie answer to this question...but you may throw a message to to the user "Not available for sometime" or something like that.
The most easy resolution is to redirect all node/%/edit to a page abc on your backup server. This can be done by doing some hacks.
Else install path_redirect module on your backup server to do that.
It would be better to redirect than to disable as disabling the core functionality would impact at many places.

gaellafond’s picture

@arijit_dutta
Thanks for the suggestion, but I really have to disable the login. Editing an article was just an example. A user may find an other way to log in to the server. I don't think it's safe to block all known ways to login since I may forget one somewhere.

I will probably have to do something like what j2r proposed.

szantog’s picture

If you have two drupal system, in the backup system's settings.php define a variable, like $no_more_login = TRUE

In hook_form_alter try something, like this:

$disabled_form_ids = array(
  'login_form_block',
  'login_form', 
  'comment_form',
//and more form id to unset.
)
if (variable_get($no_more_login, FALSE) && in_array($form_id, $disabled_form_ids)) {
  $form['#access'] = FALSE;
  drupal_set_message(t('This is a backend server, no way to create new content'));
}

No login_form, no login.

gaellafond’s picture

@szantog
Nice! I like that one! I can just create an extra config file to set the $no_more_login and exclude that file from the rsync process. It's clean and it will not crash after drupal updates since the hook can be added to the theme. Also, I think I have seen a function that return all forms so I don't have to find them all and risk to forget one.

Thank you!

cj-a-min’s picture

Doesn't seem to be working. My situation is not the same as the poster, but the end result is. Remove any and all possibilities of user writing to the master DB. This is the best option I've seen so far; if only it worked!

I tried all combination as you can see, and tried with a mycustom.module, tried settings.php, and tried template.php.

//Disable all forms
$disabled_form_ids = array(
  'login_form_block',
  'login_form',
  'comment_form',
  'form_user_login',
  'user_login_form',
  'user_login',
  'user',
  'settings_form',
  'user-login',
  'login-form-block',
  'login-form',
  'comment-form',
  'form-user-login',
  'user-login-form',
  'user-login',
);
if (variable_get($no_more_login, FALSE) && in_array($form_id, $disabled_form_ids)) {
  $form['#access'] = FALSE;
  drupal_set_message(t('This is a backend server, no way to create new content'));
}

Placed the following in the settings.php

$no_more_login = TRUE;

Refreshed all caches internal and external.

Doesn't seem to have any affect.

VivekDubey’s picture

I agree with @cj-a-min, this code is not working, and can @szantog explain it little more to make it work. If @gaellafond has used it successfully then let us know how we too can use it.
It is urgently required so please help.
Thanks

jimboh’s picture

StatusFileSize
new230.3 KB

I have written a little module that allows you to disable login to specified roles and also prevent new registrations and disable new password requests.

Like the op I have several sites that have a fallback solution (using dnsmadeeasy) that when the master server is unavailable for a specified period of time users are automatically rerouted to my backup server, but as they are ecommerce sites I want uses to be able to browse the site (and store) but not login and or make any changes because when the master site comes back online, I dont want to have to reconcile the data from backup to master (the master data is copied to the backup nightly). Because of the issue with the master overwriting data on the backup I have allowed configuration of what roles can login and what can not login based on the server IP (and the data is identical on each server so wont get overwritten).
I have attached a pic of the config screen, it may explain better.
The current version is for drupal 7 but it should not be too difficult to mod for 6.
I am not an experienced module maker so there may be better ways of doing things but if anyone would like to take a look/give it a try, let me know. Also if you can see any pitfalls or ways it could be improved...

It could also be used on just a single site scenario just to disable access when needed (without putting the site in maint mode)

I also disable checkout buttons in ubercart but that bit can just be not enabled

Edit:
Should have mentioned its currently in my sandbox at http://drupal.org/sandbox/jimboh/1525552

semei’s picture

Is it possible that your sandbox only contains logindisablebyip but not login_disable_by_role?

Edit: Pardon me, my bad.

jimboh’s picture

Sorry about the confusion I renamed the project from logindisablebyip to login_disable_by_role because I thought that better described it, but I forgot to change the actual module itself so its still called logindisablebyip. I will rename the files/module. I also have the module running on live D6 site now as well as D7 so will have to work out how to upload multiple core versions (I rarely use git).

I have also just realised it does not prevent a user that is already logged in from staying logged in... it should disconnect them. I will take a look at what is required. I had thought that in my case, where the slave is unavailable anyway due to dns this was not an issue. But with long session cookie times it still could be. Clearing the session table will do it but might mess with other modules hooks to logout. My module maintains admin settings that prevent/disable access. Not sure that adding action of kicking current users is appropriate. I will add an additional sub module that has a kick function.... it doesn't have to be enabled!

kelvinchong1976’s picture

hihi! Does anyone have better solution to disable user login? Thanks.

mdupont’s picture

Issue summary: View changes
Status: Active » Fixed

Albeit it should work by using form_alter() on user_login and user_login_block forms to disable access to the form or add a custom validate callback that would return an error, there are many ways to prevent logged-in users. A brute-force one could be to add this in a custom module hook_init():

function my_module_init() {
 global $user;

  if (user_is_logged_in() && [conditions to detect your site is running on the backup server]) {

    // Destroy the current session:
    session_destroy();

    // Load the anonymous user
    $user = drupal_anonymous_user();
  }
}

This way if anyhow a user is able to log in, he will be logged out right away.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.