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

use strict;

sub cmdListCRR {

    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 "NEW_CRR" ) {
	$name = "New Certificate Revocation Requests";
        $item_list->{HEAD}->[0] = gettext ("Sender");
        $item_list->{HEAD}->[1] = gettext ("Certificate's Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Submitted On");
        $item_list->{HEAD}->[4] = gettext ("Affected Role");
    } elsif ( $dataType eq "PENDING_CRR" ) {
	$name = "Pending Certificate Revocation Requests";
        $item_list->{HEAD}->[0] = gettext ("Sender");
        $item_list->{HEAD}->[1] = gettext ("Certificate's Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Submitted On");
        $item_list->{HEAD}->[4] = gettext ("Affected Role");
    } elsif ( $dataType eq "SIGNED_CRR" ) {
	$name = "Signed Certificate Revocation Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Certificate's Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Signed On");
        $item_list->{HEAD}->[4] = gettext ("Affected Role");
    } elsif ( $dataType eq "APPROVED_CRR" ) {
	$name = "Approved Certificate Revocation Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Certificate's Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Approved On");
        $item_list->{HEAD}->[4] = gettext ("Affected Role");
    } elsif ( $dataType eq "ARCHIVED_CRR" ) {
	$name = "Archived Certificate Revocation Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Certificate's Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Archived On");
        $item_list->{HEAD}->[4] = gettext ("Affected Role");
    } elsif ( $dataType eq "DELETED_CRR" ) {
	$name = "Archived Certificate Revocation Requests";
        $item_list->{HEAD}->[0] = gettext ("Operator");
        $item_list->{HEAD}->[1] = gettext ("Certificate's Serial");
        $item_list->{HEAD}->[2] = gettext ("Submit Name");
        $item_list->{HEAD}->[3] = gettext ("Deleted On");
        $item_list->{HEAD}->[4] = gettext ("Affected Role");
    } 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 );

    $rows = $elements;
    @list = $db->listItems( DATATYPE => $dataType, 
                            ITEMS    => $maxItems,
                            FROM     => $from );

    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));
    }

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

        next if (not $req);

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

       	$serial = $parsed->{REVOKE_CERTIFICATE_SERIAL};
       	my $crr_cert = $db->getItem (DATATYPE => "CERTIFICATE", KEY => $serial);

       	$date   =  ( $parsed->{SUBMIT_DATE} or "---" );

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

        if ($dataType =~ /(NEW|PENDING)/) {
            if ($parsed->{SIGNATURE}) {
                ## signature-based revocation
                if (my $sig = libGetSignatureObject ( OBJECT => $req )) {
                    if (my $cert = libGetSignerCertificateDB( SIGNATURE=> $sig )) {
                        $item_list->{BODY}->[$pos]->[$index++] =
                            $cert->getParsed()->{DN};
                    } 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 {
                    $item_list->{BODY}->[$pos]->[$index++] =
                        gettext("Cannot build object from signature!");
                    print STDERR i18nGettext ("Cannot build object from signature (CRR: __SERIAL__).",
                                              "__SERIAL__", $key)."\n";
                }
            } elsif ($parsed->{REVOKE_CERTIFICATE_DN}) {
                ## pin-based revocation
                $item_list->{BODY}->[$pos]->[$index++] =
                    $parsed->{REVOKE_CERTIFICATE_DN};
            } else {
                ## last chance by strong ssl-authentication
                $item_list->{BODY}->[$pos]->[$index++] =
                    $head->{SSL_CERT_DN};
                print STDERR i18nGettext ("submitter of CRR not determinable (CRR: __SERIAL__).",
                                          "__SERIAL__", $key)."\n";
            }
       	} else {
            # get operator from first signature
            if (not $req->getParsed()->{SIGNATURE}) {
  	        $item_list->{BODY}->[$pos]->[$index++] =
                    gettext("Request was not signed!");
            } else {
                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 {
                    $item_list->{BODY}->[$pos]->[$index++] =
                        gettext ("Cannot build PKCS#7-object from signature!");
                    print STDERR i18nGettext ("Cannot build object from signature (CRR: __SERIAL__).",
                                              "__SERIAL__", $key)."\n";
                }
            }
        }

        $ser_col = "<a class=\"list\" href=\"$self?cmd=viewCRR&dataType=$dataType" .
                   "&key=$key\">". $serial ."</a>";

        $item_list->{BODY}->[$pos]->[$index++] = $ser_col;
        $item_list->{BODY}->[$pos]->[$index++] =
            ( $parsed->{REVOKE_CERTIFICATE_DN} or "<CENTER>---</CENTER>" );

        if ( $dataType !~ /PENDING/i ) {
            $item_list->{BODY}->[$pos]->[$index++] =
                (  $parsed->{DELETED_DATE} or $parsed->{APPROVED_DATE} or gettext ("n/a"));
        } else {
            $item_list->{BODY}->[$pos]->[$index++] =
                ( $date or "<CENTER>---</CENTER>" );
        }

        if ($crr_cert) {
            $item_list->{BODY}->[$pos]->[$index++] =
                ($crr_cert->getParsed()->{HEADER}->{ROLE} or gettext("n/a"));
        } else {
            $item_list->{BODY}->[$pos]->[$index++] =
                gettext("Cannot load affected certificate!");
        }
    }

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

1;

