## OpenCA - Command
## (c) 1998-2001 by Massimiliano Pala and OpenCA Group
## (c) Copyright 2002-2004 The OpenCA Project
##
##   File Name: listCSR
##       Brief: Build CSR Listing
## Description: Build CSR Listing given correct dataType
##  Parameters: viewFrom, dataType, ra

use strict;

sub cmdListCSR {

    our ($query, $db, $self);

    # our $DEBUG =1;

    my $from     = ( $query->param( 'viewFrom' ) or 0 );
    my $dataType = $query->param( 'dataType' );
    my ($name, $exp);
    my ($item_list, $cmd_panel) = (undef, undef);

    my ( $dateColTitle, $rows, @cols, @list );

    ## Differentiate the list parameters
    if(  $dataType eq "PENDING_REQUEST" ) {
        $name = "Pending Certificate Signing Requests";
        $item_list->{HEAD}->[0] = gettext ("Serial");
        $item_list->{HEAD}->[1] = gettext ("Submit Name");
        $item_list->{HEAD}->[2] = gettext ("Submitted On");
        $item_list->{HEAD}->[3] = gettext ("Requested Role");
        $item_list->{HEAD}->[4] = gettext ("Requested LOA");
    } elsif( $dataType eq "NEW_REQUEST" ) {
        $name = "New Certificate Signing Requests";
        $item_list->{HEAD}->[0] = gettext ("Serial");
        $item_list->{HEAD}->[1] = gettext ("Submit Name");
        $item_list->{HEAD}->[2] = gettext ("Submitted On");
        $item_list->{HEAD}->[3] = gettext ("Requested Role");
        $item_list->{HEAD}->[4] = gettext ("Requested LOA");
    } elsif	( $dataType eq "RENEW_REQUEST" ) {
        $name = "Renewed Certificate Signing Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Renewed On");
        $item_list->{HEAD}->[4] = gettext ("Requested Role");
        $item_list->{HEAD}->[5] = gettext ("Requested LOA");
    } elsif( $dataType eq  "SIGNED_REQUEST" ) {
        $name = "Signed Certificate Signing Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Signed On");
        $item_list->{HEAD}->[4] = gettext ("Requested Role");
        $item_list->{HEAD}->[5] = gettext ("Requested LOA");
    } elsif( $dataType eq  "APPROVED_REQUEST" ) {
        $name = "Approved Certificate Signing Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Approved On");
        $item_list->{HEAD}->[4] = gettext ("Requested Role");
        $item_list->{HEAD}->[5] = gettext ("Requested LOA");
    } elsif ( $dataType eq "DELETED_REQUEST" ) {
        $name = "Deleted Certificate Signing Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Deleted On");
        $item_list->{HEAD}->[4] = gettext ("Requested Role");
        $item_list->{HEAD}->[5] = gettext ("Requested LOA");
    } elsif ( $dataType eq "ARCHIVED_REQUEST" ) {
        $name = "Archived Certificate Signing Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Archived On");
        $item_list->{HEAD}->[4] = gettext ("Requested Role");
        $item_list->{HEAD}->[5] = gettext ("Requested LOA");
    } else {
	configError(gettext("The requested list is not available."));
    }

    ## Get required parameters ( return only the value string )
    my $maxItems = getRequired( "maxReturnedItems" );
    my $elements = $db->elements( DATATYPE=>$dataType );

    my $ra  = ( $query->param('ra') or "All" );
    my $loa = ( $query->param('loa') or "" );
    $ra = "All" if $ra eq gettext("All");

    if( (not $ra) or (($ra =~ /All/i) and ($loa eq "") )) {
        ## this if both have all selected
        $rows = $elements;
        @list = $db->listItems( DATATYPE => $dataType, 
                                ITEMS    => $maxItems,
                                FROM     => $from );
    }elsif ((not $ra) or ($ra =~ /All/i)){
        ## if the ra has all selected but 
        $rows = $db->elements(DATATYPE=>$dataType);
        @list = $db->searchItems( DATATYPE => $dataType,
                                  ITEMS    => $maxItems,
                                  FROM     => $from,
                                  LOA      => $query->param('loa'));
    }elsif ((not $ra) or ($ra =~ /All/i)){
        ## if the loa has  all selected
        $rows = $db->elements(DATATYPE=>$dataType);
        @list = $db->searchItems( DATATYPE => $dataType,
                                  ITEMS    => $maxItems,
                                  FROM     => $from,
                                  RA       => $query->param('ra'));
    } else {
        ##if All was not selected in either the RA or LOA
        ## $rows = $db->rows(DATATYPE=>$dataType, RA=>$query->param('ra'));
        $rows = $db->elements(DATATYPE=>$dataType);
        @list = $db->searchItems( DATATYPE => $dataType, 
                                  ITEMS    => $maxItems,
                                  FROM     => $from, 
                                  RA       => $query->param('ra'),
                                  LOA      => $query->param('loa'));
    }

    if (not @list) {
        $cmd_panel->[0] = $query->buildRefs(
                              ELEMENTS  => $rows,
                              MAXITEMS  => $maxItems,
                              FACTOR    => 5,
                              MODE      => "EXP",
                              NOW_FIRST => 0,
                              NOW_LAST  => 0,
                              FIRST     => 0,
                              LAST      => 0);
    } else {
        $cmd_panel->[0] = $query->buildRefs(
                              ELEMENTS  => $rows,
                              MAXITEMS  => $maxItems,
                              FACTOR    => 5,
                              MODE      => "EXP",
                              NOW_FIRST => $list[0]->getSerial($dataType),
                              NOW_LAST  => $list[scalar (@list) -1]->getSerial($dataType),
                              FIRST     => libDBGetFirstItem ($dataType)->getSerial($dataType),
                              LAST      => libDBGetLastItem ($dataType)->getSerial($dataType));
    }

    ## get list of the LOAs type
    my  $loaOption = getRequired('USE_LOAS');
    my ($loaTwig, $xmlLOA, %LOALevels, );
    if ($loaOption =~ m/yes/i)
    {
        $loaTwig = loadConfigXML ('LOAConfiguration');
        if (not $loaTwig) {
            generalError (gettext ("Cannot load menu configration"));
        }

        #$xmlLOA = $twig->get_xpath('loa');
        my @loaList;
        for my $al ($loaTwig->get_xpath("loa"))
        {
            $xmlLOA = gettext(($al->first_child('name'))->field);

            $LOALevels{gettext(($al->first_child('level'))->field)}=$xmlLOA;

            push (@loaList, $xmlLOA);
            debug_cmds ("listCSR: \@loadList @loaList");
            debug_cmds ("listCSR: LOALevel 10: $LOALevels{10}");
        }
    }

    ## Process all CSRs
    $item_list->{BODY} = [];
    foreach my $req ( @list ) {
        my ( $head, $parsed, $format, $key, $ser_col, $serial, $date, $loa  );
        my @vals;

        ## We have no problem either if it is a PEM or SPKAC
        ## request as the REQ mod will try to recognize it.
        ## my $req = new OpenCA::REQ( SHELL=>$openssl,
        ##                         DATA=>$reqData);

        next if (not $req);

        my $pos = scalar @{$item_list->{BODY}};
        my $index = 0;
        $parsed = $req->getParsed();
        $head   = $parsed->{HEADER};
        $key    = $req->getSerial();

        $serial = $req->getSerial();
        $date   =  ( $parsed->{NOTBEFORE} or $head->{NOTBEFORE} or "---" );

        if ( not $serial ) {
            $serial = "<CENTER>---</CENTER>";
        };

        my $lnk = new CGI({cmd=>"viewCSR", dataType=>"$dataType", key=>$key});
        $ser_col = $lnk->a({-class=>"list", -href=>"?".$lnk->query_string()}, "$serial");

        ## get the name of the loa to display
        if ($loaOption =~ m/yes/i)
        {	
            $loa = $LOALevels{$head->{LOA}};
            debug_cmds ("listCSR: LOA in head is $head->{LOA} and loa is $loa");
        }

        if ($dataType !~ /(NEW|PENDING)/) {
            ## get operator from first signature
            if (my $sig = libGetSignatureObject ( OBJECT => $req )) {
                if (my $cert = libGetSignerCertificateDB( SIGNATURE=> $sig )) {
                    $item_list->{BODY}->[$pos]->[$index++] =
                        "<a class=\"list\" href=\"$self?cmd=viewCert&key=".
                        $cert->getSerial()."\">".
                        $cert->getSerial()."</a>";
                } else {
                    $item_list->{BODY}->[$pos]->[$index++] =
                        gettext ("Cannot determine certificate from signature!");
                    print STDERR i18nGettext ("Cannot determine certificate from signature (CRR: __SERIAL__).",
                                              "__SERIAL__", $key)."\n";
                }
           	} else {
                if (not $req->getParsed()->{SIGNATURE}) {
                    my $operator = ( $parsed->{OPERATOR} or $head->{OPERATOR} or gettext("n/a"));
                    if ($operator =~ /n\/a/i) {
                        $operator = gettext("n/a");
                    }
                    $item_list->{BODY}->[$pos]->[$index++] = $operator;
                } else {
                    $item_list->{BODY}->[$pos]->[$index++] = 
                        gettext ("Cannot build PKCS#7-object from signature!");
                    print STDERR i18nGettext ("Cannot build object from signature (CSR: __SERIAL__).",
                                              "__SERIAL__", $key)."\n";
                }
            }
        }

        $item_list->{BODY}->[$pos]->[$index++] = $ser_col;
        if ( $head->{SUBJECT} ) {
            $item_list->{BODY}->[$pos]->[$index++] = $head->{SUBJECT};
        } elsif ( $parsed->{DN} ) {
            $item_list->{BODY}->[$pos]->[$index++] = $parsed->{DN};
        } else {
            $item_list->{BODY}->[$pos]->[$index++] = "<CENTER>---</CENTER>";
        }

        if ( $dataType !~ /(NEW|PENDING|RENEW)/i ) {
            $item_list->{BODY}->[$pos]->[$index++] =
                ( $head->{DELETED} or $head->{APPROVED} or gettext("n/a"));
        } else {
            $item_list->{BODY}->[$pos]->[$index++] =
                ( $head->{NOTBEFORE} or gettext("n/a"));
        }
        $item_list->{BODY}->[$pos]->[$index++] =
            ($head->{ROLE} or gettext("n/a"));
			
        $item_list->{BODY}->[$pos]->[$index++] =
            ($loa or gettext("n/a"));
    }

    return libSendReply (
                         "NAME"      => gettext ($name),
                         "ITEM_LIST" => $item_list,
                         "CMD_PANEL" => $cmd_panel,
                         "TIMESTAMP" => 1
                        );
}

1;

