#!/usr/bin/perl -w 

#---------------------------------------------------------------------
# Copyright (C) 2011-2014 Firewall-Services
# daniel@firewall-services.com
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
#----------------------------------------------------------------------
package    esmith::FormMagick::Panel::userinfo;

use strict;

use esmith::FormMagick;
use esmith::AccountsDB;
use esmith::ConfigDB;
use esmith::cgi;
use esmith::util;
use List::MoreUtils qw(uniq);
use File::Basename;
use Exporter;
use Carp qw(verbose);

our @ISA = qw(esmith::FormMagick Exporter);

our @EXPORT = qw(
    print_user_table
    print_section_bar
    get_name
    get_shares
    get_ldap_value
    print_save_button
    get_prop
);

our $accountdb = esmith::AccountsDB->open();
our $configdb = esmith::ConfigDB->open();

sub new {
    shift;
    my $self = esmith::FormMagick->new();
    $self->{calling_package} = (caller)[0];
    bless $self;
    return $self;
}

sub print_user_table {
    my $self = shift;
    my $q = $self->{cgi};

    my @users = $accountdb->get('admin');
    push @users, $accountdb->users();

    unless ( scalar @users ) {   
        print $q->Tr($q->td($self->localise('NO_USER_ACCOUNTS')));
        return "";
    }
    print "  <tr>\n    <td colspan=\"2\">\n      ";
    print $q->start_table ({-CLASS => "sme-border"}),"\n        ";
    print $q->Tr(
        esmith::cgi::genSmallCell($q, $self->localise('ACCOUNT'),"header"),
        esmith::cgi::genSmallCell($q, $self->localise('USER_NAME'),"header"),
        esmith::cgi::genSmallCell($q, $self->localise('ACTION'),"header",4)
    );

    my $scriptname = basename($0);

    foreach my $u (@users) {
        my $username = $u->key();
        my $first    = $u->prop('FirstName');
        my $last     = $u->prop('LastName');

        my $action1 = "<a href=\"$scriptname?page=0&page_stack=&acctName=$username&wherenext=Modify\">" .
                      $self->localise('MODIFY') . "</a>";
        my $action2 = "<a href=\"$scriptname?page=0&page_stack=&acctName=$username&wherenext=Audit\">" .
                      $self->localise('AUDIT') . "</a>";

        print $q->Tr(esmith::cgi::genSmallCell($q, $username,"normal"),"        ",
        esmith::cgi::genSmallCell($q, "$first $last","normal"),"        ",
        esmith::cgi::genSmallCell($q, "$action1","normal"),"        ",
        esmith::cgi::genSmallCell($q, "$action2","normal"));
    }

    print qq(</table></td></tr>\n);

    return "";
}

sub print_section_bar{
        my $self = shift;
        print "  <tr>\n    <td colspan='2'>\n";
        print "<hr class=\"sectionbar\"/>\n";
        return undef;
}

sub get_shares {
    my ($self, $mode) = @_;
    my $q = $self->{cgi};

    my $user = $q->param('acctName');

    my @read;
    my @write;

    # Loop through all the ibays to check which ones are accessible
    foreach my $ibay ($accountdb->ibays){
        my $name = $ibay->key;
        my $desc = $ibay->prop('Name');
        my $group = $ibay->prop('Group');
        next unless $accountdb->is_user_in_group($user, $group);
        my $perm = $ibay->prop('UserAccess');
        if ($perm eq 'wr-admin-rd-group'){
            push @read, $name . " ($desc)";
        }
        else{
            push @write, $name . " ($desc)";
        }
    }
    # Now check shared folders
    foreach my $share ($accountdb->get_all_by_prop(type=>'share')){
        my $name = $share->key;
        my $desc = $share->prop('Name');
        foreach my $group (split /[;,]/, ($share->prop('ReadGroups') || '')){
            push @read, $name . " ($desc)" if $accountdb->is_user_in_group($user, $group);
        }
        foreach my $u (split /[;,]/, ($share->prop('ReadUsers') || '')){
            push @read, $name . " ($desc)" if $user eq $u;
        }
        foreach my $group (split /[;,]/, ($share->prop('WriteGroups') || '')){
            push @write, $name . " ($desc)" if $accountdb->is_user_in_group($user, $group);
        }
        foreach my $u (split /[;,]/, ($share->prop('WriteUsers') || '')){
            push @write, $name . " ($desc)" if $user eq $u;
        }
    }
    @write = uniq @write;
    @read = uniq @read;
    my @tmp = ();
    foreach my $r (@read){
        push @tmp, $r unless grep { $r eq $_ } @write;
    }
    @read = @tmp;
    my @res = ($mode eq 'write') ? @write : @read;
    return join "<br>", @res;
}

sub get_name {
    my ($self) = @_;
    return get_ldap_value($self, 'FirstName') . " " . get_ldap_value($self, 'LastName');
}

sub get_ldap_value {
    my ($self, $field) = @_;

    my $user = $self->{cgi}->param('acctName');

    return $accountdb->get("$user")->prop("$field") || '';
}

sub print_save_button {

    my ($self) = @_;

    $self->print_button("SAVE");
}

sub modify_user {
    my ($self) = @_;
    my $acctName = $self->{cgi}->param('acctName');

    unless (($acctName) = ($acctName =~ /^(\w[\-\w_\.]*)$/)) {
        return $self->error($self->localise('TAINTED_USER',
            { acctName => $acctName }));
    }
    # Untaint the username before use in system()
    $acctName = $1;

    my $acct = $accountdb->get($acctName);
    my $acctType = $acct->prop('type');

    if ($acctType eq "user" || $acctName eq 'admin') {
        $accountdb->remove_user_auto_pseudonyms($acctName);
        my %newProperties = (
            'FirstName'      => $self->{cgi}->param('FirstName'),
            'LastName'       => $self->{cgi}->param('LastName'),
            'Phone'          => $self->{cgi}->param('Phone'),
            'Company'        => $self->{cgi}->param('Company'),
            'Dept'           => $self->{cgi}->param('Dept'),
            'City'           => $self->{cgi}->param('City'),
            'Street'         => $self->{cgi}->param('Street'),
            'PostalCode'     => $self->{cgi}->param('PostalCode'),
            'Mobile'         => $self->{cgi}->param('Mobile'),
            'Extension'      => $self->{cgi}->param('Extension'),
            'Fax'            => $self->{cgi}->param('Fax'),
            'Function1'      => $self->{cgi}->param('Function1'),
            'Function2'      => $self->{cgi}->param('Function2'),
            'Function3'      => $self->{cgi}->param('Function3'),
            'Function4'      => $self->{cgi}->param('Function4'),
            'Initials'       => $self->{cgi}->param('Initials'),
            'AltEmail1'      => $self->{cgi}->param('AltEmail1'),
            'AltEmail2'      => $self->{cgi}->param('AltEmail2'),
            'AltEmail3'      => $self->{cgi}->param('AltEmail3'),
            'AltEmail4'      => $self->{cgi}->param('AltEmail4'),
            'PreferredEmail' => $self->{cgi}->param('PreferredEmail'),
            'Category'       => $self->{cgi}->param('Category'),
            'Url'            => $self->{cgi}->param('Url'),
            'Shell'          => $self->{cgi}->param('Shell'),
            'DesktopShell'   => $self->{cgi}->param('DesktopShell'),
            'ChrootDir'      => $self->{cgi}->param('ChrootDir'),
        );

        $acct->merge_props(%newProperties);

        $accountdb->create_user_auto_pseudonyms($acctName);

        undef $accountdb;

        my $event = ($acctName eq 'admin') ? 'user-modify-admin':'user-modify';
        unless (system ("/sbin/e-smith/signal-event", "$event",
                        $acctName) == 0) {
            $accountdb = esmith::AccountsDB->open();
            return $self->error('CANNOT_MODIFY_USER');
        }
        $accountdb = esmith::AccountsDB->open();
    }
    $self->success('USER_MODIFIED');
}

sub pseudonym_clash {
    my ($self, $first) = @_;
    $first ||= "";
    my $last     = $self->{cgi}->param('LastName') || "";
    my $acctName = $self->{cgi}->param('acctName') || "";

    my $up = "$first $last";

    $up =~ s/^\s+//;
    $up =~ s/\s+$//;
    $up =~ s/\s+/ /g;
    $up =~ s/\s/_/g;

    my $dp = $up;
    $dp =~ s/_/./g;

    $dp = $accountdb->get($dp);
    $up = $accountdb->get($up);

    my $da = $dp->prop('Account') if $dp;
    my $ua = $up->prop('Account') if $up;
    if ($dp and $da and $da ne $acctName) {
        return $self->localise('PSEUDONYM_CLASH', {
            acctName => $acctName,
            clashName => $da,
            pseudonym => $dp->key
        });
    }
    elsif ($up and $ua and $ua ne $acctName) {
        return $self->localise('PSEUDONYM_CLASH', {
            acctName => $acctName,
            clashName => $ua,
            pseudonym => $up->key
        });
    }
    else {
        return "OK";
    }
}

sub numbers_or_empty {
    my ($self, $field) = @_;
    my $ret =  $self->localise('BAD_SYNTAX');

    $ret = "OK" if (($field =~ m/\d+/) || ($field eq ''));
    return $ret;
}

sub email_or_empty {
    my ($self, $field) = @_;
    my $ret =  $self->localise('BAD_SYNTAX');

    $ret = "OK" if (($field =~ m/^[a-zA-Z][a-zA-Z0-9\._\-]*\@?([a-zA-Z0-9\._\-]*)?$/) || ($field eq ''));
    return $ret;
}

sub url_or_empty {
    my ($self, $field) = @_;
    my $ret =  $self->localise('BAD_SYNTAX');

    $ret = 'OK' if (($field =~ m/^https?:\/\/[a-zA-Z0-9\._\-\/]*/) || ($field eq ''));
    return $ret;
}

sub dir_exists_or_empty {
    my ($self, $field) = @_;
    my $ret = $self->localise('DIR_DOES_NOT_EXIST');

    $ret = 'OK' if ((-d "$field") || ($field eq ''));
    return $ret;
}

sub exec_exists_or_empty {

    my ($self, $field) = @_;
    my $ret = $self->localise('IS_NOT_AN_EXECUTABLE');

    $ret = 'OK' if ((-x "$field") || ($field eq ''));
    return $ret;
}

1;
