<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># Copyright 1999-2006, Fred Steinberg, Brown Bear Software

# Add/Delete users, set passwords
package SysUsers;
use strict;
use CGI;

use Calendar::AdminPager;
use Calendar::GetHTML;
use Calendar::TableEditor;
use Calendar::User;

use vars ('@ISA');
@ISA = ('Operation');

sub perform {
    my $self = shift;
    my ($save, $cancel) = $self-&gt;getParams (qw (Save Cancel));

    if ($cancel or $self-&gt;calendarName) {
        print $self-&gt;redir ($self-&gt;makeURL({Op =&gt; 'SysAdminPage'}));
        return;
    }

    my $cgi  = CGI-&gt;new;
    my $i18n = $self-&gt;I18N;

    my @columns   = qw (Username Email DefaultCal TimeZone Password IsLocked);
    my %colLabels = (Username   =&gt; $i18n-&gt;get ("Username"),
                     Email      =&gt; $i18n-&gt;get ("Email Address"),
                     DefaultCal =&gt; $i18n-&gt;get ("Default Calendar"),
                     TimeZone   =&gt; $i18n-&gt;get ("Timezone Offset"),
                     Password   =&gt; $i18n-&gt;get ("Set New Password"),
                     IsLocked   =&gt; $i18n-&gt;get ("Locked"),
                     );
    my %colTypes = (DefaultCal =&gt; 'popupMenu',
                    TimeZone   =&gt; 'popupMenu',
                    IsLocked   =&gt; 'checkbox');
    my $numAddRows = 3;

    my @calendars = sort {lc($a) cmp lc($b)} MasterDB-&gt;getAllCalendars;

    my $stet = ' - - - ';

    my (@messages, @errors);

    if ($save) {
        $self-&gt;{audit_formsaved}++;
        my $ted = TableEditor::ParamParser-&gt;new (columns    =&gt; \@columns,
                                                 key        =&gt; 'Username',
                                                 numAddRows =&gt; $numAddRows,
                                                 params  =&gt; $self-&gt;rawParams);
        my @deletedKeys = $ted-&gt;getDeleted;
        my $rowHashes   = $ted-&gt;getRows;
        my $newRows     = $ted-&gt;getNewRows;

        my @deletedUsers;
        foreach my $username (@deletedKeys) {
            my $me = $self-&gt;getUsername || '';
            if ($username eq $me) {
                push @errors, $i18n-&gt;get ('You cannot delete yourself.');
                next;
            }
            push @deletedUsers, $username;
            MasterDB-&gt;removeUser ($username);
        }

        # And remove the deleted user permissions from each calendar
        if (@deletedUsers) {
            foreach (@calendars, undef) {
                my $perms = defined $_ ? Permissions-&gt;new ($_)
                                       : Permissions-&gt;new (MasterDB-&gt;new);
                my $uhash = $perms-&gt;getUserHash;
                foreach my $user (@deletedUsers) {
                    delete $uhash-&gt;{$user};
                }
                $perms-&gt;setUserHash ($uhash) if (@deletedUsers);
            }
            my $x = @deletedUsers &gt; 1 ? 'Deleted Users' : 'Deleted User';
            push @messages, $i18n-&gt;get ($x) . ': ' .
                            join ', ', sort {lc $a cmp lc $b} @deletedUsers;
            $self-&gt;{audit_deletedUsers} = \@deletedUsers;
        }

        # Modify existing ones
        $self-&gt;{audit_modifiedUsers} = {};
        while (my ($name, $vals) = each %$rowHashes) {
            my $user = User-&gt;getUser ($name);
            next unless $user;
            my @mods;
            if (($vals-&gt;{Email} || '') ne ($user-&gt;email || '')) {
                $user-&gt;setEmail ($vals-&gt;{Email});
                push @mods, 'Email';
            }
            if (($vals-&gt;{TimeZone} || 0) != ($user-&gt;timezone || 0)) {
                $user-&gt;setTimezone ($vals-&gt;{TimeZone});
                push @mods, 'TimeZone';
            }
            my $defaultCal = $vals-&gt;{DefaultCal} eq $stet ? undef
                                                         : $vals-&gt;{DefaultCal};
            if (($defaultCal || '') ne ($user-&gt;defaultCalendar || '')) {
                $user-&gt;setDefaultCalendar ($defaultCal);
                push @mods, 'DefaultCal';
            }
            if ($vals-&gt;{Password} ne $stet) {
                $user-&gt;setPassword ($vals-&gt;{Password});
                push @mods, 'Password';
            }
            if ($vals-&gt;{IsLocked} xor $user-&gt;isLocked) {
                $user-&gt;setLocked ($vals-&gt;{IsLocked});
                push @mods, 'IsLocked';
            }
            if (@mods) {
                push @messages, $i18n-&gt;get ('Changed User') . ": $name; " .
                                       join (', ', map {$colLabels{$_}} @mods);
                $self-&gt;{audit_modifiedUsers}-&gt;{$name} = \@mods;
            }
        }

        # Add new ones
        my @newNames;
        foreach my $row (@$newRows) {
            my $name = $row-&gt;{Username};
            next if (!$name);
            if ($name =~ /\W/) {
                my $blah = $name;
                $blah =~ s/[-@\.\\]//g;
                if ($blah =~ /\W/) {
                    push @errors, "$name: " .
                                  $i18n-&gt;get ('Invalid Username') . '; ' .
                                  $i18n-&gt;get ('Only letters, digits, ' .
                                              'underscores, periods, @, and ' .
                                              'backslashes are allowed in ' .
                                              'user names.');
                    next;
                }
            }
            my $defaultCal = $row-&gt;{DefaultCal} eq $stet ? undef
                                                         : $row-&gt;{DefaultCal};
            my $password   = $row-&gt;{Password} eq $stet ? undef
                                                         : $row-&gt;{Password};
            my $newUser = User-&gt;create (name       =&gt; $name,
                                        email      =&gt; $row-&gt;{Email},
                                        defaultCal =&gt; $defaultCal,
                                        zoneOffset =&gt; $row-&gt;{TimeZone},
                                        isLocked   =&gt; $row-&gt;{IsLocked},
                                        password   =&gt; $password);

            if ($newUser-&gt;addUser) {
                push @newNames, $name;
            } else {
                push @errors, "&lt;font color=red&gt;" . $i18n-&gt;get ('Error') .
                              ":&lt;/font&gt; " . $i18n-&gt;get ('User') .
                              " &lt;b&gt;$name&lt;/b&gt; " . $i18n-&gt;get('already exists!');
            }
        }
        if (@newNames) {
            my $x = @newNames &gt; 1 ? 'Added Users' : 'Added User';
            push @messages, $i18n-&gt;get ($x) . ': ' .
                            join ', ', sort {lc $a cmp lc $b} @newNames;
            $self-&gt;{audit_addedUsers} = \@newNames;
        }
    }

    unshift @calendars, $stet;

    my $h = $i18n-&gt;get ('hours');
    my %tzLabels;
    foreach (-23..23) {
        $tzLabels{$_} = "$_ $h";
    }

    my %colParams = (Email      =&gt; {size =&gt; 25},
                     DefaultCal =&gt; {values =&gt; \@calendars},
                     TimeZone   =&gt; {values  =&gt; [-23..23],
                                    default =&gt; 0,
                                    labels  =&gt; \%tzLabels});

    my $ted = TableEditor-&gt;new (columns       =&gt; \@columns,
                                key           =&gt; 'Username',
                                columnLabels  =&gt; \%colLabels,
                                types         =&gt; \%colTypes,
                                controlparams =&gt; \%colParams,
                                tableTitle    =&gt; $i18n-&gt;get ('Users'),
                                numAddRows    =&gt; $numAddRows,
                               );

    my @users = sort {lc($a-&gt;name) cmp lc($b-&gt;name)} User-&gt;getUsers;
    my $pager = AdminPager-&gt;new (op       =&gt; $self,
                                 contents =&gt; \@users,
                                 itemName =&gt; $i18n-&gt;get ('users'));
    my @displayThese = $pager-&gt;getDisplayList;

    foreach my $user (@displayThese) {
        next unless $user;
        my $row = $ted-&gt;addRow (Username   =&gt; $user-&gt;name,
                                Email      =&gt; $user-&gt;email,
                                DefaultCal =&gt; $user-&gt;defaultCalendar,
                                TimeZone   =&gt; $user-&gt;timezone || 0,
                                Password   =&gt; $stet,
                                IsLocked   =&gt; $user-&gt;isLocked);
    }

    print GetHTML-&gt;startHTML (title =&gt; $i18n-&gt;get ('User Administration'),
                              op    =&gt; $self);
    print GetHTML-&gt;SysAdminHeader ($i18n, 'Add, Modify, or Delete Users', 1);

    if (@errors) {
        print '&lt;p&gt;', join ('&lt;br&gt;', @errors), '&lt;/p&gt;'
    }
    if (@messages) {
        print '&lt;p&gt;', join ('&lt;br&gt;', @messages), '&lt;/p&gt;'
    }

    print '&lt;br&gt;';
    print $cgi-&gt;startform;
    print $ted-&gt;render;

    print $pager-&gt;controls;

    print $cgi-&gt;submit (-name =&gt; 'Save',   -value =&gt; $i18n-&gt;get ('Save'));
    print '&amp;nbsp;';
    print $cgi-&gt;submit (-name =&gt; 'Cancel', -value =&gt; $i18n-&gt;get ('Done'));
    print '&amp;nbsp;&amp;nbsp;&amp;nbsp;';
    print $cgi-&gt;reset  (-value =&gt; 'Reset');
    print $cgi-&gt;hidden (-name =&gt; 'Op', -value =&gt; __PACKAGE__);
    print $cgi-&gt;endform;

    print '&lt;br&gt;&lt;b&gt;' . $i18n-&gt;get ('Notes') . ':&lt;/b&gt;';

    print $cgi-&gt;ul (
            $cgi-&gt;li ($i18n-&gt;get (
               "The 'Default Calendar' is the calendar that is displayed " .
               "after the user logs in. It's also the calendar events are " .
               "added to for this user, via the 'Add Event' link in event " .
               "notification email.")),
            $cgi-&gt;li ($i18n-&gt;get ("'Locked' users cannot change any of " .
                                  'their own user settings.'))
                   );

    print $cgi-&gt;end_html;
}

sub cssDefaults {
    my $self = shift;
    my $css = $self-&gt;SUPER::cssDefaults;
    $css .= GetHTML-&gt;AdminCSS ($self);
    $css .= $self-&gt;cssString ('.PasswordInput',  {'text-align' =&gt; 'center'});
    return $css;
}

sub auditString {
    my ($self, $short) = @_;
    return unless $self-&gt;{audit_formsaved};
    my $line = $self-&gt;SUPER::auditString ($short);

    my $i18n = $self-&gt;I18N;

    my $space = $short ? '' : ' ';
    my $newl  = $short ? ' ' : "\n";

    $line .= $newl;

    if (my $x = $self-&gt;{audit_deletedUsers}) {
        $line .= $i18n-&gt;get ('Deleted') . ":$space" . join ",$space", @$x;
        $line .= $newl;
    }

    my $x = $self-&gt;{audit_modifiedUsers};
    if (keys %$x) {
        while (my ($name, $mods) = each %$x) {
            $line .= $i18n-&gt;get ('Modified') . ":$space$name$space-$space" .
                     join ",$space", @$mods;
            $line .= $newl;
        }
    }

    if (my $x = $self-&gt;{audit_addedUsers}) {
        $line .= $i18n-&gt;get ('Added') . ":$space" . join ",$space", @$x;
        $line .= $newl;
    }

    return $line;
}

1;
</pre></body></html>