Changeset 358


Ignore:
Timestamp:
Mar 11, 2010, 2:35:27 PM (11 years ago)
Author:
zerodeux
Message:

Refactored login logic + using simple and single 'master_password' a la Mailman

Location:
bearmail
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • bearmail/conf/bearmail.conf

    r355 r358  
    44# or web-based, mail filters and so on.
    55
    6 # backend - choose where and how account configuration is stored
     6# backend - Choose where and how account configuration is stored
    77#
    88# Backend::Files (path)
     
    2323
    2424
    25 # Global postmaster
    26 # Can manage all domains
     25# master_password - Global super-user password.
    2726#
    28 global_postmaster_login = nickname_or_email
    29 global_postmaster_password = MD5password
     27# This password can be used with any domain or administrative login
     28# such as 'root' or 'admin' to login with the web interface and
     29# get super-user privileges (view and manage all domains).
     30#
     31# The value should be a MD5 hash (32 hexadecimal digits).
     32#
     33# Example:
     34# master_password = 21232f297a57a5a743894a0e4a801fc3
     35#
     36master_password = no_hash_no_superuser
    3037
    3138
  • bearmail/lib/BearMail/Web/Login.pm

    r354 r358  
    2929    my $pass  = $q->param('password') || '';
    3030
    31     if(($self->cfg('global_postmaster_login') eq $email)
    32         and ($self->cfg('global_postmaster_password') eq md5_hex($pass))) {
     31    # We can't proceed with login if we don't have both params
     32    return $self->login_page() if $email eq '' or $pass eq '';
    3333
    34         $self->session->param('user', $email);
    35         $self->session->param('level', 'admin');
    36         my $intent = $self->session->param('intent') || 'domain_list';
    37         warn "Login successful, redirecting to intent='$intent'";
    38         return $self->redirect($self->url($intent));
     34    # FIXME: need to handle simple user login too
    3935
    40     } elsif(exists($self->{b}->get_postmasters()->{$email})
    41             and $self->{b}->get_postmasters()->{$email} eq md5_hex($pass)) {
     36    # First check simple domain login
     37    my $domain_pass = $self->{b}->get_postmasters()->{$email};
     38    return $self->login_ok($email, 'postmaster')
     39        if defined $domain_pass and $domain_pass eq md5_hex($pass);
    4240
    43         $self->session->param('user', $email);
    44         $self->session->param('level', 'postmaster');
    45         my $intent = $self->session->param('intent') || 'domain_list';
    46         warn "Login successful, redirecting to intent='$intent'";
    47         return $self->redirect($self->url($intent));
    48     }
     41    # Then try master password, but only on amdin|root logins to prevent
     42    # users discovering domain/master password collisiona by accident
     43    my $master_pass = $self->cfg('master_password');
     44    return $self->login_ok($email, 'admin')
     45        if defined $master_pass and $master_pass eq md5_hex($pass) and
     46           $email =~ /^(admin(inistrator)?|root)$/i;
     47
     48    return $self->login_page();
     49}
     50
     51sub login_page {
     52    my $self = shift;
    4953
    5054    my $tmpl = $self->load_tmpl('login.html');
     
    5256}
    5357
     58sub login_ok {
     59    my $self = shift;
     60    my ($user, $level) = @_;
     61
     62    # Store authentified user in session (privileges should be checked at
     63    # every operation instead of being stored in s{level}, FIXME)
     64    $self->session->param('user', $user);
     65    $self->session->param('level', $level);
     66
     67    # Redirect to the original page the user intended to go, or some fitting
     68    # default page depending on user privileges.
     69    my %default = (
     70      user       => 'address_edit',
     71      postmaster => 'address_list',
     72      admin      => 'domain_list',
     73    );
     74    my $intent = $self->session->param('intent') || $default{$level};
     75    return $self->redirect($self->url($intent));
     76}
     77
    54781;
Note: See TracChangeset for help on using the changeset viewer.